Re:C pointers are not hardware pointers
by dzdt on Sunday March 06, 2016 @02:58PM
(#11235272)
Seriously? I have seen this code many places, even written it.
[ Parent
| on HN ]
#include <stdio.h>
typedef float xform_3d[4][3];
int main() {
xform_3d x = {
{1.f, 0.f, 0.f},
{0.f, 1.f, 0.f},
{0.f, 0.f, 1.f},
{0.f, 0.f, 0.f} };
for(int i=0; i<12; i++) printf("%f\n", x[0][i]);
}
with g++ 4.9 (debian jessie -O3 -Wall): xf.c: In function βint main()β:
xf.c:12:50: warning: iteration 3u invokes undefined
behavior [-Waggressive-loop-optimizations]
for(int i=0; i<12; i++) printf("%f\n", x[0][i]);
^
xf.c:12:5: note: containing loop
for(int i=0; i<12; i++) printf("%f\n", x[0][i]);
^
(yes, this is slightly different than the code I posted first---"laundering" &x[0][0] through an intermediate pointer variable f makes the warning go away in the compiler I tested, but my suspicion is that if one is undefined behavior the other probably is too)Edited to add: and when built and run, it printed all x[0][i] but x[0][0] as 0.0, so gcc did emit code that doesn't do what the programmer wants.
> my suspicion is that if one is undefined behavior the other probably is too
I would suspect otherwise. I have no particularly good reason for that, but the cases with and without warnings match to my expectations of what's valid and what's not. Intuitively, I'd expect pointers can point to any valid memory, while array accesses can only be done within the dimensions of the array.
You may be right. I haven't gone and read the standard yet, but I also fed related programs to cbmc 4.9, a C-program verifier, using the -bounds-check flag. It tags x[0][3] as an out-of-bounds access, but not f = &x[0][0]; f[3]; (also (x[0]+i) is OK according to cbmc, despite what we all learned about (a+b) and a[b] being the same!)
Neither variant is picked up as illegal at runtime by -fsanitize=address and gcc-4.9 or clang-3.5.