Opened 14 months ago
Closed 11 months ago
#286 closed defect (fixed)
typeof Decays Array Types
Reported by: | ajbeach | Owned by: | |
---|---|---|---|
Priority: | major | Component: | cfa-cc |
Version: | 1.0 | Keywords: | |
Cc: |
Description ¶
C (and hence CFA) does have a habit of replacing arrays with pointers. However there are a few places it should not be decomposed and one of those is inside a typeof. In some cases this does appear to be happening.
I did some simple checks inside sizeof (and repeated them in alignof, but they just play out exactly the same) that looks like this:
char array[2]; _Static_assert(sizeof(char[2]) == 2 * sizeof(char)); _Static_assert(sizeof(typeof(char[2])) == 2 * sizeof(char)); _Static_assert(sizeof(array) == 2 * sizeof(char)); _Static_assert(sizeof(typeof(array)) == 2 * sizeof(char)); _Static_assert(alignof(char[2]) == alignof(char)); _Static_assert(alignof(typeof(char[2])) == alignof(char)); _Static_assert(alignof(array) == alignof(char)); _Static_assert(alignof(typeof(array)) == alignof(char));
The first two cases, where we examine the type directly, play out as you would expect, when translation is done the wrapped type is still char[2]. Similarly, in the third case, the sizeof(array) remains unchanged. Only in the forth case sizeof(typeof(array)) is converted to sizeof(char *) which gives the incorrect result.
This is not limited to the operators-on-types, here is a case where it happens as a direct type in a declaration. Checking the translated code confirms that ptr is in fact a pointer to character type.
int main(int argc, char * argv[]) { char array[2] = {5, 7}; typeof(array) ptr; ptr = &array[1]; }
Change History (3)
comment:1 Changed 14 months ago by
comment:2 Changed 14 months ago by
I checked, against the standard (via cppreference.com, not quite the standard itself) and I ran the same tests through C. The alignof block doesn't work because that is not in standard C. The sizeof block works, all the static assertions pass. The function on the other hand stops working, the assignment expression does not work. I added some more expressions and yes it seems to be a length two array again. Oh and going back
Oh, and the standard says that "No implicit conversions are applied to expression." which seems different than the C++ decltype, if that means no pointer decay it matches the tests.
https://en.cppreference.com/w/c/language/sizeof
https://en.cppreference.com/w/c/language/typeof
comment:3 Changed 11 months ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
Made a new ticket for the related error (#287). This case is solved.
I can see where it is coming from. This bears some resemblance of C++ decltype(expr) vs decltype(id) difference. In C++'s case it also affects the result of reference typing. We only have the former in our typeof semantics, and a variable of array type used as an id-expression becomes pointer type (rightfully) and so this happens.