[Bug c++/45249] Indirect variable parameters sometimes cause segmentation fault

rogerio at rilhas dot com gcc-bugzilla@gcc.gnu.org
Wed Aug 11 22:17:00 GMT 2010



------- Comment #35 from rogerio at rilhas dot com  2010-08-11 22:16 -------
(In reply to comment #33)
> Yes GCC implements that ABI and &argument will get you the address of that
> argument.

If that is so then the format parameter will be placed at some address X, param
1 at address X+4, param 2 at address X+8, and param 3 at X+12. Figure 3-48
shows these addresses to be very predictable and well defined. It is very
important for you to follow this reasoning, as this makes all the difference.
This is what makes X an array of 4 entries, and not simply an array of 1
isolated entry.


> But that does not deter from that &argument will produce an array of
> size 1 rather than what you want which is the rest of the arguments too.

Can you backup your claim that "&argument will produce an array of size 1"? Can
you even backup the claim that &argument "produces" any array at all? As I
showed using C99, the & just produces a value X (an address which can be
travelled without boundary issues), so C99 shows that "&argument" does not
"produce" an array, nor allocates storage for a 1-entry copy of "argument" at
some unpredictable address Y (C99 clearly states that &a retuns "address of a",
not "address of copy of a"). So I don't see how you could ever backup your
claim with any standard, but I'm open to be surprised by your creativity! :-)

Based on C99 const char** PTR4=&format will set PTR4 to X. It's all good as
long as PTR4 contains the value X. As C99 defines this, GCC doesn't have the
option to copy the "format" to some random address Y and return it when I ask
for "&format". It simply should not do this. I've backed this claim with C99
text that states that & operator is the address of the item, not the address of
a copy of the item invented by the compiler.

I also showed you in C99 that PTR4[0] accesses the 4 bytes of address X, and
I've backed up my claim (based on C99) that PTR4[1] will access the 4 bytes at
X+4 (i.e the 4 bytes of param 1), and that there is no "size of array
limitation" specified in C99. Similarly, PTR4[2] will access the 4 bytes at
X+8, (i.e the 4 bytes of param 2), and so on. I've clearly backed up this with
C99.

So, all this is backed up. Can you refute the reasoning up to this point with
any C99 reference? Or a reference to any other standard for that matter?

> Does that answer your question about how I could just ignore the ABI in the
> context of the C/C++ standard?  The ABI only says how they are passed and not
> how you can access them through C/C++ code.

So no, not really. If the ABI is respected then the 4 parameters will be stored
at predictable places, all together, as a 4-entry array at address X, which is
fundamental for me to access them using a PTR4 set to X.

If you told me right from the start that GCC didn't comply to cdecl, or that it
did but only sometimes, then this conversation would have ended immediately,
because I would have absolutely no way to trust that the 4 items would be
present at contiguous bytes X to X+15, and I would, therefore, not be able to
access PTR4[1], PTR4[2], and so on. This should help you understand why the ABI
is an important part of this problem, and where I base my claim that GCC's
behaviour is wrong.

So, if GCC were not cdecl-compliant, I would have no other option but to shut
up and think about new approaches in my code. Well, maybe I would not just shut
up and maybe I would then complain that GCC should be cdecl-compliant always,
but I would not call it a bug and I would post it as a feature request.

You could reason that the ABI was not important if the compiler were free to
create a copy of "format" to some address Y when I ask for "&format" (as in
that case it would probably just copy "format" and not the remaining 3
parameters to location Y - hence you would be right, an array of size 1), but
C99 says the compiler cannot do that because &format is X (the address of the
item, not Y the address of a copy of it).

But GCC does not return X when I ask for "&format", at least not always (as
sometimes returns a random Y), and it should (as I backed up with C99).

If under GCC "&argument will produce an array of size 1 [with a copy of format
and not of the other parameters]" then you would be right and you would be
proving GCC to have a bug that contradicts C99.

If GCC didn't have a bug it would comply with C99 and would return X, which the
cdecl ABI states is a 4-entry array, not 1-entry array as you claimed (making
your claim wrong).

So you are right because GCC has a bug, if it hadn't you would be wrong. In
other words, what you say in fact happens in real life because GCC is not
strictly conforming to C99 (and while that happens you are right to say that is
the current behaviour to "&argument will produce an array of size 1"), but if
GCC behaved as C99 says it should then what you say would not be hapening in
real life (and so you would be wrong when saying "&argument will produce an
array of size 1").

I have the feeling I was able to explain myself better this time. Was I?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45249



More information about the Gcc-bugs mailing list