[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-14 Thread rogerio at rilhas dot com


--- Comment #52 from rogerio at rilhas dot com  2010-08-14 13:17 ---

Do you really want me to go away? You are not using the right formula for that.
You know I have a problem and I can't resist. Everytime you post a message
you're just calling me back!



(In reply to comment #49)
You're rude, ignorant and annoying.

Yes I am. But a little bit less every day, thanks to (respectively) my mom,
your clarifications about the standards, and my 12-step program.



(In reply to comment #51)
  There you go, you are now famous.
  http://en.wikipedia.org/wiki/GNU_Compiler_Collection#Criticism


Why did you remove the post? Do you think something there is not true? You said
it, why is it not true? Are you recanting? Wikipedia is the place to post true
statements, it if is the truth then it should be there. Don't tell me now that
you are ashamed of what you said, are you?

Please: you and your friends keep of from removing a perfectly valid criticism
that I backed up with your statements. You think you can just keep on removing,
but I'll just keep on putting it back. Until I get bored and take it up to
Wilkipedia. Why didn't you remove the other guy's criticism about GCC being
buggy and producing crappy code? Is his criticism better than mine? Is it
better substantiated than mine?


 Thank you, that's encouraging, I just hope the language of that article won't
 be changed too much to also mention everyone else who has a clue.


No, from the time I posted it first I changed it only once because I realised
(based on it being undefined right now) that the code could break at any time,
not just with future releases of GCC.


  Because,
 you see, I'm of course very excited about me being famous now and about being
 the only one who knows the truth, but OTOH I fear there were some other
 clever people that happen to agree with me, and I now see a real
 danger of those replacing me in that wikipedia article.



I don't see where you are getting at. I don't want you to be the only one who
knows the truth, I want everyone to know about it. Duhh!! Why else would I post
it on Wikipedia?? I don't want GCC to keep any secret pitfalls from anyone, is
that alright with you?




  Even worse would be
 that the list of names would be too large to mention in wikipedia and that
 the list would be replaced by some more unspecific phrases like people who
 actually understood the standard or the like.


Ah, I see. You are afraid of someone removing your name from the post? I won't
do that, I promise. And while the reference to your comment is there you will
always have a place among the stars. So be sure to try your best to keep it
there!!



  The comunity has been warned about GCC.


Everybody who reads Wikipedia. Some of them are programmers.


 Which community?  Rogerio-cdecl church followers?


Possibly. In between our other rituals. My followers use their prayer time as
they like, many of them use that time to seek enlightment. They can get it from
wherever they like, including Wikipedia. Or C standards. Or bugzilla bug
reports. Whatever.


  In that case I'm happy,
 because I'll expect less bug-reports from supporters of that specific
 religion.

Sure, you already shut me up. And I thanked you, remember? (I still have the
same opinion of you, but your error rate dropped a little more... still
impressivly high, though). I confessed that I did learn from your post (not
being sarcastic, I really did).



  I'll continue to feel sorry for them (especially because I've
 learned over the conversation that you might actually influence new
 programmers, which is a terrible thing to do for you) but am not particularly
 looking forward to seeing misguided and crippled attempts of creating
 meagre imitations of stumbling pseudo bug-reports, especially because we
 can have the best there is: Rilhas bugs!

Yup. I now realize why my bug reports aren't really bug report. Just some
side-effect of me not realizing the full impact of GCC just following
standards.

It claims is cdecl conformant, but even without optimizations it doesn't place
parameters on the stack as cdecl states. My bad, GCC does not guarantee cdecl
anywhere, you are right. So I'll just shut up with that.

And getting the address of parameters? You are right, not defined in the
standards. You are right too. So I'll just shut up with that too.

So, the 2 bug reports are, thus, squashed as invalid. (not being sarcastic
either).

As for Rilhas' bugs? None, as long as I steer clear of GCC. And my code works?
Yes. And am I good at what I do? Yes? How do I know? My mom tells me so all the
time (and besides I continuously get paid very well, which is my second
strongest indicator that I do a good job). Am I afraid of doing non-standard
things? No, standards have to keep up with the real world and with special
pusher compilers, like MSC. If one day some standard realizes that what MSC
does is clever and adopts it then GCC will eventually follow. If not then I'll
just keep

[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-14 Thread rogerio at rilhas dot com


--- Comment #55 from rogerio at rilhas dot com  2010-08-14 14:31 ---
(In reply to comment #53)
 (In reply to comment #52)
  (In reply to comment #51)
 Look at the page history, it was removed by someone else, probably because 
 your
 comment is badly written and not suitable for the Wikipedia page.

I thought that was your mom, sorry. We are alright then. When the guy removes
it again I'll tell him to ask you if it is true. If you don't recant he will
know I'm telling the truth.


 As with most of your comments, they are unfounded and easily refuted by
 checking facts, but you're so sure you know them that you don't need to check.
 As you've said before, learn to read.


Right, that must be it. As if I didn't backed it up with your own comment #35.
Boy, it will sure be easy to prove my post to be unfounded!!!



 Noone wants it to be a secret, everyone in the GCC project would prefer if no
 users shared your incorrect beliefs.



So do I. I don't want anyone sharing my incorrect beliefs. Did we just agree on
something here? So I'll tell the guy to talk to ask you.



 Check your favourite reference - the Wikipedia entry on cdecl says GCC is the
 de facto standard for caling conventions on Linux - so by definition what GCC
 does is correct.  It must be true, Wikipedia says so.


... unless it was your post! You tend to miss more than you hit. But yeah,
you've shut me up on that too. I just wrote that in my previous post.


 What are you talking about?  You were originally talking about initializing
 non-const references with temporaries.

Yes, that is right. GCC gave me the same error in both cases (aren't default
parameters initialized with classes the same as parameters initialized with
classes?). Probably my bad.

  The code above would work fine, if
 you'd defined Color and Vector.
 class Color { public: Color(int); };
 class Vector { public: Vector(int); };
 const int WHITE = 0;
 const int VECTOR_Z = 0;
 class Idiot {
 virtual void func(Color c = Color(WHITE), Vector v = Vector(VECTOR_Z));
 };
 GCC compiles that fine, try it.

Yeah, you are right, your class does. But mine don't, the diference is that
mine are a bit more complex and derive a lot... but you were right, yours does
compile. And I was right, my code with GCC would have given me more trouble to
deliver to the client. But you are right, I posted an Idiot class. (see how
easy it is to admit when we are wrong? .. if you tried it you would quickly
gain a lot of practice! ... anyway, good job in reducing your error rate, it is
now close to a normal person!)


 GCC compiles that because it's valid C++.
 What is your point?
 Keep this up, future employers will love to see you making an idiot of 
 yourself
 so publicly.


No, the worse is being wrong and don't admit it. When we admit we learn, so
I've been learning quite a lot with you guys. You didn't admit anything, so in
your mind LDT read accesses a still prohibitive, and crap like that. Or did you
think I would forget all the crap that you said that I shot down and you didn't
admit?? Your future employers (if any!) will see that your ability to learn
simple stuff is impaired.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-14 Thread rogerio at rilhas dot com


--- Comment #56 from rogerio at rilhas dot com  2010-08-14 14:34 ---
(In reply to comment #54)
 (In reply to comment #53)
  GCC compiles that fine, try it.
 Sorry, I forgot my manners, what I meant is...
 Why don't you think before shooting off some crap.
 So I have shown you talk crap. Do you like it?
 Better get used to it, I'm a mean sonofagun and I'll keep showing you why
 you're wrong.
 You're an idiot.

Yeah, I've seen you show me I said crap that I didn't study well enough before
saying it. I learned, it will never be repeated.

All the rap you said that I shot down didn't make you learn anything.

We are both idiots, but I'm a little bit less every day. I've left you behind a
long time ago.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-14 Thread rogerio at rilhas dot com


--- Comment #58 from rogerio at rilhas dot com  2010-08-14 16:02 ---
Why?? Why do you keep calling me back?? I was just going out and I heard the
new e-mail sound! Now I'm going to be late!!


(In reply to comment #57)
 Good way to make a convincing argument.  You've tried to turn this into a 
 your
 mom argument in three replies now, but noone seems to be rising to the bait. 

Not an argument. I said I was sorry to think it was you or one of your friends
(is Chris your friend?). Anyway, I understand why you got confused and missed
my apology, I inserted the mom joke. My bad, it was not funny at all, and you
thought it was an argument. My bad.



 Are you confusing me with Michael?  I've not said anything about LDT.

Yes I am. I'm sorry for that, I really am. I got mixed up. We were discussing
the post and I didn't check the sender. There are just too many of you guys.
I'm sorry, this comment wasn't meant for you (I must be getting tired).



 What am I supposed to admit?  That GCC compiles valid C++ code?

You don't have to admit anything really. But in your comment #34 to bug #45249
you missed the point entirely and just spewed out standards. You missed the
point really, as I was saying GCC can't, and it really can't. Spewing out
standards just to explain GCC can't because insert standards here was not
really useful for that discussion. Does not make an idiot out of you though.

Then you claimed What a charming idea, that a compiler could become perfect by
doing what I said it should. And that is very close to making an idiot out
of you, because you deflected without getting the background for the
conversation straight. I had to show you (again) that you failed to see that
what I say is what C99+cdecl say.

These all don't make an idiot out of you yet. Adding them all together was
borderline-idiot, but still safe.

Then, for this bug, your comment #45 missed the point. You didn't understand
why I posted it on Wikipedia, although it is well explained there. But ok, I'll
grant you that that also does not make an idiot out of you.

... then, from comment #53 on we really looked to me like Michael, so I lost
it. Here I go, back to being more of an idiot, and there you go not an idiot
yet.



 That I've wasted time replying to you?  That's true, but it's my weekend and
 I'm waiting for a GCC testsuite run to finish so I have time.
 You keep accusing GCC of not compiling useful C++ code, but haven't shown a
 valid example yet.

Yes I have. It is there on Wikipedia. The code compiled is not valid (in a
functional sense) because the programmer cannot trust the pointer difference.
Maybe at this point you get confused because you didn't type valid [according
to standards] example, but you didn't type it. So valid is open for
discussion. And I say that is valid if it returns 0x4000-0x3000=0x1000.

So there you go, now you're an idiot like Michael (well, still less, your error
rate is much lower and of much less significance). You are an idiot because you
don't know what valid is to everyone, you just think you do because you know
of some standard that says what is valid in a given context. I do assembly
inside my C code with MSC, is that not valid because it is not defined in any
C standard? Nope. It is valid, no matter how much you kick and scream.

With the same train of thought I could talk about initializing classes as
parameters to functions as in comment #25 of bug #45249 (as another example I
posted and that you didn't see), because, again, you didn't explain what the
valid word in your text was supposed to mean. I know you mean standards, but
there is more to it. But this one does not make an idiot out of you because
valid is much harder to define here. So I'm am not in a position to spot the
level of idiocy in your comment (I'll just assume it is none). So I say valid
(outside in the real world) and you say invalid (based on C standards), but
none of us are idiots for it.

  I am happy to learn but I don't see anything worth learning
 from you, your opinions or your debating style. Even your trolling skills 
 are
 poor, and you started so well.

That's my point. You keep proving my point. You don't feel the need to learn
anything from me because you are all cosy inside your standards box and look
down on the other kids playing outside in the real world. You wear all your
silk-based standards shirts and mock the dumb kids in the playground that use
silk+cotton immitations. You call them idiots even after they've shown you that
when you are outside silk doesn't cover all the needs. You don't even realize
that I'm right that GCC thus alienates memory mapped device programmers, thus
making it inferior to many others. You're stuck in idiot-land.

I still don't know what a troll is. English is not my native language. Checking
the web it seems like a troll is someone whose primary purpose when posting
comments is to provoke disruption. I don't feel like that, I posted what I
thought to be actual bugs

[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-13 Thread rogerio at rilhas dot com


--- Comment #34 from rogerio at rilhas dot com  2010-08-13 12:14 ---
(In reply to comment #33)

  Not really, you could always subtract. However, far pointers gave
  predictable addresses, just like C99 says they pointer arithmetic should.
 They didn't.  If you subtracted far pointers that pointed into different
 segment, the segment difference was ignored.  If you include real segmentation
 like on 80286, where there's no linear relationship between effective address
 and segment+offset, subtraction would have been prohibitively expensive to
 implement anyway.

That's just ignorance on your part (nothing new, I guess I'm becoming used to
that). You are saying things that you don't know. You said that without even
knowing if there were any compilers back then that didn't do what you said. You
just took your personal experience with some crappy compiler and generalized it
for everyone. Wrong.

What you don't know is that when you subtracted far pointers the compiler
generated the code to change seg16:ofs16 into abs20. What you think is
prohibitively expensive would come down to 4 instructions or something like
that (2 shifts, 2 additions). But lets say 10. Is that prohibitively
expensive?? If the user requested a pointer difference you would be happy as a
compiler developer to just not compile (or produce an incorrect difference)
instead of generating 10 machine instructions? Or 20?

A compiler should NEVER EVER EVER refuse to compile (or compile bad code)
because the resulting number of instructions is large. Your comment and opinion
thus don't deserve any respect because we are defending the way to do a bad
compiler. That claim is not just wrong, it is dumb. I'm not trying to offend
you, I'm sure you are not dumb, but you let a dumb comment slip out.

Anyway, again you are just plain wrong. The compilers I used back then did this
operation well. In those days there were no real standards that developers
would generally follow, and programmers used to rely on what they knew about a
compiler. So I guess you might have used some crappy one that failed miserably
at pointer arithmetic, and based your whole opinion that it is beller to
compile bad arithmetic or not compile at all than to add 10 instructions to the
code.

Your ignorance is in not knowing that segmented addresses were already being
abstracted to C programmers by mid-range compilers. I remember this being
already done on 8088 compilers, abstraction of the underlying hardware was
something every C compiler strived to do. No compiler I knew of didn't do an
operation correctly because it had to generate 10 instructions or 20. or a
loop. So you stated something as an absolute truth but failed to see that one
single exception would prove you wrong. So you you threw yourself head on
against the wall again.

But don't worry, I think I know your type fairly well. You will probably just
get right back up on the horse, shake it all off, forget about what you did
wrong, and start anew with some other wrong statement. I'm basing this on your
track record in our conversations, where almost 100% of your claims are wrong
or miss the point. That is just impressive. In case I'm wrong about you my
apologies.


  And you still wouldn't get around the size limitation of ptrdiff_t that was 
 16bit.


What the hell are you talking about? I personally disassembled code in the
late 80's to see how the compiler implemented 32-bit arithmetic on a 286. It
did, and it did it well. You weren't able to go beyond 16 bits in the 80's? Or
are just making this stuff up? I'm sure you are making it up, on an 8-bit PIC I
have written assembly code to do 32-bit shift-add and it uses up something like
12 instructions or so. Not hard at all. Not prohibitive at all.

Again: you wished you were right, but you are wrong. You think you known, but
you don't. But are you careful? No, you just keep throwing yourself against a
wall. And you don't seem to realise that that is becomming a recurring pattern
for you. Keep it up, it is fun to watch.


 And of course the subtraction of addresses of parameter is always meaningless
 in C, segmented or not, as pointed out multiple times.  With or without cdecl.


Yup, and multiple times you have been wrong. The cute C99 box you live in
doesn't let you see beyond that. But param is not meaningless if the compiler
adheres to cdecl, I've shown that numerous times, you are just unable to see
(your bad).

operation 1 - place parameters as cdecl (try to learn something here please, it
is important that you don't run away and hide inside C99):

push param3 to address X+8 on the stack
push param2 to address X+4 on the stack
push param1 to address X on the stack
call function

function:
get address of param1: MUST BE X!
get address of param2: MUST BE X+4!
get address of param3: MUST BE X+8!

But I guess you will just keep on losing yourself here because cdecl is outside
of C99. And if you try to leave the C99 box your brain crashes

[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-13 Thread rogerio at rilhas dot com


--- Comment #38 from rogerio at rilhas dot com  2010-08-13 14:47 ---
(In reply to comment #36)
   If you include real segmentation
   like on 80286, where there's no linear relationship between effective
   address and segment+offset, subtraction would have been prohibitively
   expensive to implement anyway.
  What you don't know is that when you subtracted far pointers the compiler
  generated the code to change seg16:ofs16 into abs20.
 What in the words real segmentation like on 286, where there's no linear
 relationship between effective address and segment+offset was unclear to
 you to expect that abs20==seg16*16+ofs16?  The prohibitive expensive
 referred to the necessary lookup of the base in the LDT/GDT that would have
 been required for every far pointer subtraction.

From wikipedia:

Rather than concatenating the segment register with the address register, as
in most processors whose address space exceeded their register size, the 8086
shifted the 16-bit segment only 4 bits left before adding it to the 16-bit
offset (16·segment + offset), therefore producing a 20-bit external (or
effective or physical) address from the 32-bit segment:offset pair.

So there you go: the relation between effective abs20 address and seg16:ofs16
pair. And it is a linear relation: abs20=K*seg+ofs establishes a linear
relation. Check your algebra, and check x86 operation before saying random
stuff.

Can you guess how tricky it is for a compiler to get an effective abs20 address
out of a seg:ofs pair?

abs20=seg*16+ofs (voilá! ...magic!!)

What are you dreaming about LDT/GDT? Do you think you need any of that to get
an abs20 from a seg16:ofs16 pair? Or maybe you think that a far qualifier would
noke the compiler carry seg16 and ofs16 everywhere it went? You just made that
stuff up again. Michael Michael Michael: what did I tell you about making stuff
up? You don't need to prove to anyone that you are creative, will all know that
by now.

... and if Wikipedia is not good enough for you then you can learn about
segmentation and how to compute effective addresses in many places. All will
teach you what Wikipedia shows. I would teach you if you paid me. No, scratch
that: I woudn't, so I'll just leave you alone on this one.


   And you still wouldn't get around the size limitation of ptrdiff_t that
   was 16bit.
  What the hell are you talking about? I personally disassembled code in
  the late 80's to see how the compiler implemented 32-bit arithmetic on a
  286. It did, and it did it well. You weren't able to go beyond 16 bits in
  the 80's?
 Did I say that?  Let's see: size limitation of ptrdiff_t that was 16bit.
 Nope.  I didn't.  The point being that if ptrdiff_t is only 16 bit, then
 no matter how fantastically capable the compiler was in emitting 32bit
 arithmetic, the result of subtracting to char pointers pointing more than
 64KB (or in fact 32KB) apart would not fit into a ptrdiff_t.

The code I used to do was somthing like long dif=ptr2-ptr1 (long was most
often 32-bit back then). Why the hell did you bring ptrdiff_t to the
conversation? I didn't get it, honestly. But if you brought it was was surely
to show me that there was no point in doing 20-bit arithmetic because I would
not be able to fit that result anywhere, right? Maybe not, you lost me with the
whole ptrdiff_t that you decided to bring into the conversation.


  No, not me, I don't want to write nonsense on the web,
 Maybe you don't necessarily want to.  But ... , well, there we are.


Yup. You have still to make one valid claim, and I've been easily shooting you
down everytime. And I back it up, isn't that an amazing concept? You should try
it sometime.


  I prefer to be clear headed. One never knows when stuff one wrote on the
  net will come back and bite one in the ass!!
 I'm not sure you realize just how true that is.  But keep going, you're
 by far one of the best trolls I've seen in GCC land.  Much better than
 Pizarro.

... is troll code for guy who doesn't forgive any false claims and repeatedly
shoots down and squashes people who do that repeatedly like a mean son of a
insert_repulsive_animal_here that he is?

In that case thanks! :-)


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-13 Thread rogerio at rilhas dot com


--- Comment #39 from rogerio at rilhas dot com  2010-08-13 14:48 ---
(In reply to comment #35)
  char* p1=(char*)0x3000; // address not pointing to any C-object in the C99
  sense
  char* p2=(char*)0x4000; // address not pointing to any C-object in the C99
  sense
  
  Can GCC users trust that p2-p1 will always return a predictable and well
  defined integer value of 0x1000 on any platform with 16-bit or more that GCC
  currently supports or that will come to support in the future?
 [ ] Yes
 [x] No


Thanks. The comunity will be alerted to this. I'll get back to you when your
name is in some famous place associated with this claim.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-13 Thread rogerio at rilhas dot com


--- Comment #40 from rogerio at rilhas dot com  2010-08-13 14:53 ---
(In reply to comment #37)
 (In reply to comment #36)
  I'm not sure you realize just how true that is.  But keep going, you're
  by far one of the best trolls I've seen in GCC land.
 Well, I can easily imagine more funny things to do, some even summer-specific,
 but indeed, can be interesting, from a psychological point of view, I mean ;) 

Possibly... I'm on vacation, so this morning I just played a little bit of Half
Life 2 on the console (yes, keep the wise cracks to yourself, I know I'm
severely outdated when it comes to video games!). Anyway, after about half an
hour of killing zombies and shooting down bad guys I got bored. Turned on the
PC and THERE WAS MICHAEL It is easier and more entertaining to shoot him
down than zombies with a 5 year old AI.

Then I went for a swim, had lunch with the family, and the Sun got to strong to
be outside. What else is there to do?? I know!!! Let's check on Michael again!!
:-)

So you see: I do have a problem. I will seek help. Promise. :-)


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-13 Thread rogerio at rilhas dot com


--- Comment #43 from rogerio at rilhas dot com  2010-08-13 16:28 ---
(In reply to comment #41)
 You should really adjust your glasses if you want to continue trolling with
 the high standards we're used to meanwhile:
   What in the words real segmentation like on 286, where there's no linear
   relationship between effective address and segment+offset
 So, I think it's pretty clear that I'm referring to the 80286, whereas
 you cite something ...


Oh really? Because you so cleverly used the word real to lead me to believe
you were talking about real mode 286? How clever of you, you were talking about
protected mode after all.

Ok, after interpreting your incorrect wording I can give you that: 286
protected mode was a pain. You just dropped your error rate to less than 100%,
kudos!! (should adjust your phrasing though, if you want to be correctly
inrepreted)


  From wikipedia:
  
  Rather than concatenating the segment register with the address
  register, as in most processors whose address space exceeded their
  register size, the 8086 shifted the 16-bit segment only 4 bits left
 ... about the 8086.  To make it very obvious, even to you: 86 vs 286.
 As you have so huge experiences with such old processors, I'm sure
 you can guess what I meant with real segmentation aka protected mode now. 



There is no thing as real segmentation, you must have made it up. The Linux
community seems to talk a little about it... but I never saw Intel say or write
anything about it when I was studying the 286. Linux guys use that expression,
is that why you thought it was standard?

Wrong.

What Intel defined was real mode and protected mode. So you see what you do
when you don't use your words correctly and call it real segmentation? Of
course it would look like segmentation in real mode. Your bad. Unless you can
backup real segmentation with some official doccument from Intel, can you?



 In case you still can't and because we seem to start using wikipedia to back
 up claims: http://en.wikipedia.org/wiki/X86_memory_segmentation .


No mention of real segmentation. Is this what you wanted to show me?


 Now, implement a routine that subtracts two pointer for this memory model.
 You'll see that it requires bit-magic on the segment selector,
 lookup in the GDT or LDT and finally some 24bit arithmetic to produce
 the result.


Yup, too much work. Better leave it alone and return some random pointer
subtraction number. Better yet: don't compile such code. And never again
guarantee to anyone anything about pointer subtraction unless it fits inside
C99 box.

I had one class on 286 which made us implement processes on a minimal protected
mode OS for the 286. I can tell you it isn't that hard to read the LDT or GDT,
and it didn't have any prohibitive performance penalty, contrary to what you
claim. Maybe you are confusing yourself between reading from and writing to the
GDT/LDT? Or maybe you can backup your claim that reading from GDT/LDT is
prohibitive?


  The arithmetic is of course trivial, the lookup is expensive.


Could you please back it up? That's contrary to my experience, you see, and
since it lacks logic since the processor reads to those tables were designed to
be fast to make it run fast... so I think you should back that up, otherwise it
just looks like you are making it up (not to me though, I know it wasn't
prohibitive).


 Doing it for every pointer subtract was what I called prohibitive expensive
 for a normal pointer subtraction.


Yes, you are wrong to call it prohibitive. You just want to imagine it to be
prohibitive so that you can stick to your claim that pointer subtraction result
is not guaranteed by GCC *EVER* because of the 286. What a boring
unsubstantiated argument. Without backing up such illogical claims its all just
jiberish.

So go ahead and find a techncal paper or report that shows that reading the LDT
or GDT causes a significant performance penalty. Let's set a threshold: 50
instructions? So, ok: if you can find such a document that says that accessing
those tables always costs 50 instructions or more then I'll grant you that the
compiler should have an option to disable correct pointer subtraction. I will
still not grant you an incorrect pointer subtraction by default, but I will
insert apology here in that my experience with 286 was unexplainably better
than yours. If you can't find such a document then insert apology here for
making unsubstiated claims and forget about it (apology accepted).


 That, together with the fact that all
 segments are max 2^16 in size, and that it's impossible to map back all
 24bit numbers into segmented addresses without generally adding new
 entries into the GDT/LDT made it useless to have pointer differences
 any larger than 16 bit, not impossible but useless in real compilers.
 Therefore the result of such a subtraction isn't always representable.

In the copilers I used back then the far pointer was 32-bit, just like it was
32-bit on the seg16

[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-13 Thread rogerio at rilhas dot com


--- Comment #44 from rogerio at rilhas dot com  2010-08-13 16:30 ---
(In reply to comment #35)
  char* p1=(char*)0x3000; // address not pointing to any C-object in the C99
  sense
  char* p2=(char*)0x4000; // address not pointing to any C-object in the C99
  sense
  
  Can GCC users trust that p2-p1 will always return a predictable and well
  defined integer value of 0x1000 on any platform with 16-bit or more that GCC
  currently supports or that will come to support in the future?
 [ ] Yes
 [x] No


There you go, you are now famous.

http://en.wikipedia.org/wiki/GNU_Compiler_Collection#Criticism

The comunity has been warned about GCC. It was a good day's work after all.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-13 Thread rogerio at rilhas dot com


--- Comment #46 from rogerio at rilhas dot com  2010-08-13 16:42 ---
(In reply to comment #45)
 Congratulations.  Are you done now?
 What else are you hoping to achieve?
 Is this a cry for attention?

No much really. Now it is all up to the community. I just want everyone to know
that computing pointer subtraction is not guaranteed to be accurate on GCC.

My personal gains will be (possibly):

1) Maybe the community can force GCC to start making such guarantees. That
would help all of us. The example I posted there is real, I'm not making
anything up!

2) Showing all of you that a compiler should be more than just C99. A good
compiler need to be more than C99. And an excelent compiler must be more than
just C99. All of you confine your answers to C99 forgetting that a compiler
will be used in many real world situation, for example in memory mapped
devices.

3) Showing Michael that he says a lot of crap. Show him that he just shot
himself in the foot for not thinking before speaking. Maybe get him to think
before making claims? Even with all my warnings he didn't think of people that
compile for memory mapped devices? He should think before he says something, he
is not just some random guy like me, he is a representative of the GCC project
and his answers (crap included) are GCC-binding.

I confess I get some satisfaction out of that 3rd item. But I would do it even
if I had the first 2. The community at large thinks more like I do, and expect
the pointer subtraction to always return accurate results. I'm just warning
them. I'm not lying. I'm not distorting anything. If it helps someone then
good, otherwise it can«t harm anyone, right?

That's it, really. As for the bugs I reported I have no further hope.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-13 Thread rogerio at rilhas dot com


--- Comment #48 from rogerio at rilhas dot com  2010-08-13 21:16 ---
(In reply to comment #47)
 OK, here is the deal:
 Since you want this feature so much, I'm sure that everybody would gladly
 implement it for you, for - say - measly 5000 EUR. You can then offer this
 c-like compiler to the world and save the planet. Just imagine, how the link 
 to
 this enhanced compiler would be a great addition to your Wikipedia entry!
 You can even call this custom compiler whatever you like, except gcc.
 You will rewrite the history!

It sounds like a good deal. Really, I'm not being sarcastic in any way. I would
like to have 5000 to invest on GCC.

Maybe you all got me wrong: the reason I wrote the 2 bug reports is because I
do think GCC is a *very important project for the community*. I'm being honest.
If GCC were not important I would not have gone to any trouble at all, yet
alone spend several hours writing 2 or 3 complete reports (with files and
snapshots) and many messages. Maybe it is time for you to understand what I
really am all about. I say stuff about GCC, I've called lowest common
denominator (and I mean it), but I still think it to be among the top 5 most
important compiler projects in the world (including Microsoft's and Intel's and
a bunch of comercial compilers). It could be top 1, if it weren't for being so
confined to C99 and not *want* to go beyond it.

And I would like to have 5K to put on GCC. As I said I know I can't demand
anything, after all the thing is being offered to me! Even more than that: it
is being offered to me without me having ever contributed with a bit. So, as I
said before, I'm not demanding anything (nor could I).

I was just hoping that you would see the importance of my feature (although I
still call it a bug and not a feature, and if you want I can give you examples
of why it is important to be able to initialize classes as function
parameters). You didn't see it? Or you saw it but you don't agree that it is
important? I'll insist, I'll bring new angles to the discussion. Still no? I'll
insist some more, maybe get some other examples. Nothing still? Whatever, I'll
shut up and go away, no problem. The reason I'm still here is (to a great
extent) because of Michael... that guy just cracks me up. It is possibly the
person that I've ever known that has such a high error rate (it was up to
100% for a while there!). But this conversation has stopped being about my bug
reports a long long long long time ago. I'm on vacation, so I have had more
time on my hands than I'm used to, and Half Life 2 bores me a little if I play
it for too long! :-) ... so I keep comming back. As I said before I will seek
help. Just one more, this is the last one!!! Promise!! I'll buy a new game and
leave you all alone soon! :-)

I posted the criticism on Wikipedia not to hurt anyone in particular. But I do
criticize GCC for not being able to guarantee correct pointer arithmetic. And
me, as a citizen of this world, have the right to make my criticism and post it
where everybody can see and judge for themselves. And, being an important
criticism, I should back it up. So I did, and posted 2 references.

I was very careful not to write anything that might be incorrect or misleading.
I quoted our conversation almost exactly. And even with the different words I
made sure the content is exactly the same as in my conversation with Michael. I
didn't lie. I didn't distort. I didn't exagerate. I didn't take it out of
context. I said it like it is, no more, no less.

So here is the deal to you:

If you all agree with Michael then my Wikipedia post is correct and has a
reason to exist, and people like me will want to be alerted to what it says.
Programmers don't go around reading C99, generally speaking they just try to
write good code. That's it. I would guess 90%+ of programmers don't go out
checking if their line of code is C99 conformant or not. However, I believe
their code can be more than 99.9% C99 conformant, so very little people have
any problems.

I'm one such programmer, I hadn't read C99 before talking to you but 99.9% of
what I do falls completely within the things defined in C99. But there is a
fraction of what I do that does not fall there, and I still have to do it. And
like me there are many others, who have a fraction of their work fall outside
C99 (without knowing). And the code still has to work. Always. Guaranteed. And
we trust the compiler to give us the expected result. Always. Guaranteed. If
I am wrong in trusting it then I want to be alerted. That's all I did in the
Wikipedia post: alert people that do code for memory mapped devices and similar
(like I often do).

So if you think Michael is correct then he is, in fact, a hero. He is the one
guy, on the face of this planet that I know of, that had the balls to come out
and say beware of pointer subtraction when using GCC!!. No sarcasm here, I
trully believe this.

If he is, in fact, right then I will personally thank him because up

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

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #57 from rogerio at rilhas dot com  2010-08-12 10:16 ---
(In reply to comment #56)
 Please stop wasting your and GCC developers time.  As several people have
 explained, your code triggers undefined behavior in C/C++, so it can do
 anything at runtime.  The fact that it happens to work as you expect with some
 compilers doesn't mean anything.  If you choose to program in C (or C++), you
 just need to follow the standard.  GCC bugzilla is for reporting GCC bugs, not
 for learning programming languages, look for various C forums instead.

I've clearly shown the bug in my commment #51. It is a bug in the address
operator. C99 says GCC shouldn't be doing that. The format is not undefined
behavior. In comment #36 Richard Guenther agrees that X should return the
stack address. GCC is not doing that. Please open your eyes and understand
this. It is simple. I believe you all have the brain power to understand at
least that. If you just forget all the rest and focus on X you'll see GCC has
a bug. If you fix it I can then handle the rest on my own, thank you, no need
for all your rants about standards. You are the ones who shouldn't be wasting
my time like this.


-- 

rogerio at rilhas dot com changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |


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



[Bug c++/45265] New: GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com
The following code:

void bug_example_2(const char** format_address, int* ip) {
char* p1=(char*)format_address;
char* p2=(char*)ip;
int dif=p2-p1;
if (dif!=sizeof(char*)) {
// crash
char* p=0; *p=0;
}
}

void bug_example(const char* strp, int i) {
char buffer[1000]; buffer[0]=0;
bug_example_2(strp, i);
}

int main(void) {
bug_example(GCC has a bug, 10);
return 0;
}

... is incorrectly compiled by GCC. As you can see there are no variable
parameters in this code, so there is nothing here out of the ordinary.

Possibility 1) GCC is not cdecl-ABI compliant, so the dif can have values
other than 4 on x86-32. In this case GCC should not claim to be
cdecl-compliant.

Possibility 2) GCC is not conformant to C99 but it is cdecl-ABI compliant. C99
states in section 6.5.3.2 paragraph 3 that The unary  operator yields the
address of its operand., but GCC is not doing that, as the if in
bug_example_2 is occasionally entered. Thus dif is not 4 (and with cdecl ABI
it should be 4 on x86-32).

If line char buffer[1000]; buffer[0]=0; GCC then compiles the code as
expected and dif will be 4.

This proves GCC is not conforming to C99 recommendations or that is not
cdecl-ABI compliant (or possibly both).

Don't bother trying to understand why I need the  operand to work as stated in
C99, or why I need the code to be cdecl compliant, that is too complicated for
you and it would just confuse you. For the purpose of this bug you may simply
consider that I'm performing conformity tests on GCC against C99 and cdecl, and
that GCC failed the test.

Next I will send you the preprocessed file and the compilation script.


-- 
   Summary: GCC has an intermittent bug when computing the address
of function parameters
   Product: gcc
   Version: 4.3.3
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: rogerio at rilhas dot com
 GCC build triplet: i686-virtualboxvm-ubuntu?
  GCC host triplet: i686-virtualboxvm-ubuntu?
GCC target triplet: i686-virtualboxvm-ubuntu?


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #1 from rogerio at rilhas dot com  2010-08-12 14:52 ---
Created an attachment (id=21469)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21469action=view)
Preprocessed file


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #2 from rogerio at rilhas dot com  2010-08-12 14:52 ---
Created an attachment (id=21470)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21470action=view)
Compilation script


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #3 from rogerio at rilhas dot com  2010-08-12 14:54 ---
Correction:

If line char buffer[1000]; buffer[0]=0; _is removed then_ GCC then compiles
the code as expected and dif will be 4.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #6 from rogerio at rilhas dot com  2010-08-12 15:33 ---
(In reply to comment #4)
 Pretty please, before filing further bugs take time and learn C.
 The pointer subtraction triggers undefined behavior, because one pointer 
 points
 to one object and the other pointer points to different object.

Pretty pretty please: before you give out such wrong and embarassing answers
please take the time to learn the standards and also take the time to learn how
to read.

I'm subtracting 2 pointers of the same type. If you knew how to read you would
have seen that p1 and p2 are of the same type. Or maybe you just don't know C,
but I'm sure you can learn it so that you can be helpful to the GCC team and
not waste my time.


 See ISO C99, 6.5.6/9.

I did read it, but it is not the case here, you got it wrong.


 In particular, in this testcase the functions are inlined

Where did you get that idea from??? They are not inlined, you are wrong, check
the assembler before imagining what is hapening.

 and thus i and strp
 are just normal automatic variables in main, obviously nothing guarantees how
 they are laid out in the stack.

Wrong, you should learn your C. You could have understood this by yourself if
you realized that i works but 10 doesn't. If you knew your basic C you would
know that both strp and i were passed by value, and so they are not the
original in the main but instead copies in bug_example. I'm sure you would
want it not to be so, to save face, but you said it now you're stuck with it.


  But even if it isn't inlined, the behavior
 would be undefined.

Wrong again. Undefined by C99 but not undefined by cdecl.

I didn't specify inline, so GCC should have made cdecl. If it didn't then GCC
should not claim to be cdecl. So choose: is it GCC's bug possibility 1 or
possibility 2?

(is it really that easy for you to write such wrong answers for everyone to see
and keep wasting my time like this??? ... do you think that helps GCC?)


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #7 from rogerio at rilhas dot com  2010-08-12 15:33 ---
(In reply to comment #5)
 ISO/IEC 9899:1999, 6.9.1 Function definitions
 9. Each parameter has automatic storage duration. Its identifier is an lvalue,
 which is in effect declared at the head of the compound statement that
 constitutes the function body (and therefore cannot be redeclared in the
 function body except in an enclosed block). *The layout of the storage for
 parameters is unspecified.*

Wrong again. Undefined by C99 but not undefined by cdecl. So choose: is it
GCC's bug possibility 1 or possibility 2?


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #11 from rogerio at rilhas dot com  2010-08-12 16:04 ---
(In reply to comment #8)
 (In reply to comment #6)
  (In reply to comment #4)
   Pretty please, before filing further bugs take time and learn C.
   The pointer subtraction triggers undefined behavior, because one pointer 
   points
   to one object and the other pointer points to different object.
  
  Pretty pretty please: before you give out such wrong and embarassing answers
  please take the time to learn the standards and also take the time to learn 
  how
  to read.
 Bravo, well trolled.
  I'm subtracting 2 pointers of the same type. If you knew how to read you 
  would
  have seen that p1 and p2 are of the same type. Or maybe you just don't know 
  C,
  but I'm sure you can learn it so that you can be helpful to the GCC team and
  not waste my time.
 Please stop trying to use GCC, we'll all be better off.

Oh and that will make your colleague Jakub right about p1 and p2 be of diferent
types? Does it make his answer intelligent? Sure, whatever you say, I'll follow
your recommendation.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #15 from rogerio at rilhas dot com  2010-08-12 16:15 ---
(In reply to comment #14)
 I never claimed p1 and p2 have different types.  They have the same type.
 But the standard paragraph I mentioned says:
 When two pointers are subtracted, both shall point to elements of the same
 array object, or one past the last element of the array object
 That is not the case in your testcase, strp and i are different objects.

char* p1=random_address();
char* p2=another_random_address();

p1-p2 is always well defined, no matter to which objects they point to. After
the subtracion they will point to objects of the same type (char's). So, you
don't know your C nor C99 (we are reading it wrong).


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #17 from rogerio at rilhas dot com  2010-08-12 16:18 ---
(In reply to comment #12)
 Seriously, go away.  I'll get far ruder if you're going to open bug reports
 worded like this:
 (In reply to comment #0)
  Don't bother trying to understand why I need the  operand to work as 
  stated in
  C99, or why I need the code to be cdecl compliant, that is too complicated 
  for
  you and it would just confuse you.


... o... now you got me scared. I will just go away before you call me
C-ignorant or something really insightful like that.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #18 from rogerio at rilhas dot com  2010-08-12 16:18 ---
You know what? I did a small sample showing this bug to other people. They all
understood it, but not you. They all know what it means C99+cdecl at the same
time. You don't. I'm surprised at your lack of capacity for uderstanding. Well,
as long as you are proud of yourselves then that is what really matters, right?
Good luck with that.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #22 from rogerio at rilhas dot com  2010-08-12 17:24 ---
(In reply to comment #21)
 Even without optimization (as the compilation script uses), the program
 crashes.

Right, that was the point of introducing the 1000-character buffer. With it it
crashes always.

  To be concrete about what's going wrong based on what the assembly
 code actually looks like (GCC version Ubuntu 4.4.3-4ubuntu5):
 bug_example:
 pushl%ebp
 movl%esp, %ebp
 subl$1048, %esp # space for buffer
 movl8(%ebp), %eax   # move string elsewhere
 movl%eax, -1020(%ebp)
 movl%gs:20, %eax# stuff for stack checking
 movl%eax, -12(%ebp)
 xorl%eax, %eax
 movb$0, -1012(%ebp)
 leal12(%ebp), %eax  # address of i to stack
 movl%eax, 4(%esp)
 leal-1020(%ebp), %eax   # address of (copied) strp to stack
 movl%eax, (%esp)
 callbug_example_2
 movl-12(%ebp), %eax
 xorl%gs:20, %eax
 je.L6
 call__stack_chk_fail
 .L6:
 leave
 ret
 .sizebug_example, .-bug_example
 You are assuming that in `bug_example' that the parameters passed to
 `bug_example_2' must be the addresses of those variables *as they were passed
 on the stack*.  This is certainly one way of implementing it, but it is not
 mandated by the standard (as comment #9 points out).

You are absolutelly right, I fully agree that a non-cdecl conformant GCC would
not need to pass parameters on the stack. It only has to pass parameters on the
stack (in a very well-defined way) if it claims to be cdecl-compliant. But even
with the cdecl specifier in the source the generated assembly code is wrong.
Hence a bug.

Hadn't you realized yet that that is my point from the start


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #23 from rogerio at rilhas dot com  2010-08-12 17:25 ---
(In reply to comment #19)
 Everyone understands it, you're just wrong.

No I'm not, the problem seems to be just to complex for you because you would
have to tie up C99+cdecl to understand, but you don't understand it because you
don't know cdecl language (this still makes me laugh!) and so you don't get
out of your little C99 box (which makes you lose sight of the big picture).

char* p1=random_address();
char* p2=another_random_address();

Any compiler that does not predictably compute p2-p1 is a piece of crap. You
can twist C99 all you want, but whenever p2-p1 is left to some undefined
criteria of the compiler then it is just an absolute piece of crap. Period.
That is why no compiler leaves this indefined, even GCC (apparently it was just
luck). This should be enough for you to see you are not getting C99 right,
because following what you say would create crappy compilers. Feel free to try
and prove they would not be crappy.

Even if you could convince me of your interpretation of C99 and p2-p1 were not
well defined, you would still have to explain why strp is not 4 bytes before
i (not subtracting, just looking at their disassembled addresses). This is
the big picture that you do not understand, you just keep deflecting.

... while we discuss GCC still doesn't return the correct address for strp.

So, let me just summarize by saying I was so so so so wrong to expect GCC to
have returned the address that my little brain expected to result from the
combination C99+cdecl. Of course I was wrong and you were right, which makes me
stupit and you smart.

Meanwhile everyone else knows that if it compiles in GCC and executes
correctly then it compiles and executes correctly in any other compiler... can
you deduce why? Does it make you proud? ... hint: which do you think is the
compiler with the most reduced capabilities that serves as a baseline for your
code? Would you like to keep GCC at this low end of the spectrum? Good, just
keep on insisting on your interpretation of C99.

http://en.wikipedia.org/wiki/GNU_Compiler_Collection

In 2007, GCC received criticism from one OpenBSD developer who complained that
GCC is mostly developed by companies, that it is large, buggy, slow, and that
it generates poor code,[31][not in citation given][32] and who also dislike v3
of the GNU GPL.[33] The OpenBSD project and FreeBSD projects, respectively, are
experimenting with replacing GCC with the Portable C Compiler[33] and
Clang/LLVM.[34] The NetBSD and DragonFlyBSD projects have commented that on
replacing GCC, they have explored various compiler replacements but have no
solid answers.[35] (I've checked the references, they are fine!!)

Does it have anything to do that you dismiss people who find and show you bugs?
Maybe you do a good job when you quickly send them away after stamping it with
non-conformant, I don't know, but I expected a little more interest on your
part to make GCC better. I would be open to anything, including something along
the lines of ok, it is not a bug, but we will consider this as a feature
request... but not even that.

I'll come back some day (be afraid!! :-) ) with a list of compilers tested to
see how many produce correct results for this bug report. For now in 4
compilers tested (2 from Microsoft) 3 of them do the job correctly and GCC is
the only one that doesn't. Oopss...! I meant: GCC is the only one to have
correctly interpreted C99, the other 3 got it wrong and let me get the
addresses of the parameters as I wrongfully expected. And let me subtract them
predictably. This surelly proves you are very insightfull and that you know C99
better than anyone else.

Gone, sorry for any inconvenience.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #24 from rogerio at rilhas dot com  2010-08-12 17:50 ---
(In reply to comment #20)

I couldn't resist to comming back (you respond very quickly, kudos!, I'm not
used to that! :-)

 Just for fun, I compiled this test case with various levels of optimization. 
 It works fine without optimization or with -O1, but segfaults at -O2 or -O3.

The script I sent you does not request optimizations and segfaults.

 That indicates that the program only works by coincidence, not by design -
 you've made assumptions about how GCC will interpret your sources, and those
 assumptions are wrong.  In this case, your assumption is that bug_example_2
 will always be a separate function, and will always be called as a separate
 function, and thus that you can assume some knowledge of the internals of the
 stack layout.

When I don«t request optimizations my interpretation is right. A function
declaration (that doesn't specifically request inline) is a function. I don't
know if C99 says it (probably does, in a C-sense function), but cdecl does.

 The C language does *not* require that a function which is called, be called 
 as
 a separate function, only that the semantics of the call be the same as far as
 the C language requires.  The C language allows GCC to implement that function
 call in any way it chooses - and GCC chooses to implement it without actually
 doing a function call, but by copying the function body to the callee.  At
 least, it does when optimizing.  Without optimization, it *happens* to do what
 you expect.

Compile it like I did in the script (without optimizations) and see it fail.

  It will also do what you expect if bug_example_2 and bug_example
 are in separate source files - *then* the cdecl standard you refer to
 applies, because cross-object calls are limited by the compatibility 
 standards.
 However - if you use gcc to link as well, gcc has the option of optimizing
 those calls *also*.
 So, GCC is cdecl compliant because *if* there's a function call, *then* the
 *stack* is laid out the same.  However, the cdecl standard does *not* 
 require
 that your program work, because C allows the optimizer to avoid the actual
 function call completely when the callee and caller are in the same scope.

Incorrect, code should not be optimized if I don't request it. If I do I have
to live without cdecl compliance, obviously, as I don't know of any compiler
that has an option like optimize_as_possible_but_keep_cdecl_always. My point
is for non-optimized code, and that is why I included the scrip I used to build
it.

 Note: you can tell gcc to not inline a function with __attribute__((noinline))
 in which case a call to it is always an actual call to it, but it would be
 easier to just use the standard methods for accessing parameters so that it
 *always* works.

Agreed. But I'm determining the addresses of the parameters just to check GCC's
conformity, remember? So don't you worry about how easy the code is for me, I
will deal with that.

I just tried the attribute and didn't make any difference in the code, and is
still not cdecl. I'm sure it is not a bug in GCC though...

 Also, with full optimization enabled, your code crashes with MSVC also.

Right. As explained, this bug report is about non-optimized code. I also didn't
expect Microsoft's code to not crash if optimized (nor tried it until your
comment).

I don't think I ever mentioned optimizations in this bug report, I did it in
the variable parameters bug report bucause that was how I initially got it to
crash and had no way to report it to you (it crashed without optimizations in a
larger program that I could not send to you), but I later sent you a full
report (with snapshots and all in comment #51) a non-optimized version that
crashed. Here I could easilly show it to crash when not optimized, and so I
could live with disabling optimizations to get the addresses to be returned
properly.


 Please file a bug report with Microsoft.

No need. Their code *NEVER* crashes if I don't request optimizations.

This is it, I must resist! Bye!! :-)


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #26 from rogerio at rilhas dot com  2010-08-12 18:04 ---
 You opened this bug report with insults, what sort of response do you expect?
 GCC is too crappy and amateur for your awesome code, so I suggest you stick to
 better compilers.

Will do, thanks.

... and sorry for my opening lines, I was very pissed off that after a great
deal of work making a full report you didn't see that problem was not related
to the variable arguments and it seemed to me that you were not even bothering
to to read it, and kept dismissing me as trying to do non-conformat things.
That is what motivated me to isolate the problem for this bug report, and I am
sorry I was unable to put on a happy face, my bad.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #29 from rogerio at rilhas dot com  2010-08-12 18:24 ---
(In reply to comment #27)
 Oh, this fun.  Enjoyable, really! ;-)

Again I couldn't resist! Everytime I'm ready to go away you say something
shocking that I simply can«t resist. Its time for me to admit I have a problem!
:-)

 So, you admit that MSVC does in fact miscompile your perfectly fine cdecl
 code, if you request optimization from it?

Yes.

  How bad is that of them?

Not perfect, but still better than GCC, because at least I can get it to work.

 Terrible!

... n... that's just your jealousy talking because you can't even begin to
understand how to make a temporary variable an l-value... how can someone be
defending a compiler that never conforms (GCC) to one that conforms if I don't
request it to optimize? That's just bad logic. It's not my intention to insult
you, but the observation itself lacks any underlying logic.

  I would consider creating a bug report with them, because if they
 miscompile your code with optimizations it must surely be their bug.

No, optimizations take away room for assumptions. That's why GCC can optimize
for(i=0; istrlen(sp); i++). What??? GCC didn't call strlen() every time? How
stupid! No, you are just lacking logic. Drink something with vitamins and get
out more, it will do you good.

  After
 all optimization is a process of transforming a valid program into another
 program that behaves exactly the same, hence if they optimize your valid
 program into a crasher, what else could it be than a bug in their compiler?

Read my strlen() example. That shows you are wrong. You invented that
definition, you can't really back it up otherwise strlen() would have to be
called every time.

 I mean, really.  They are supposed to provide a commercial grade compiler.
 How can it be that they force you to deactivate optimization options
 (and hence live with slow runtime) just so that your valid cdecl program
 doesn't crash?

Yup, money can only buy so much. No money can buy you alittle bit less.

 One side remark about your p2-p1 claim:
  char* p1=random_address();
  char* p2=another_random_address();
  
  Any compiler that does not predictably compute p2-p1 is a piece of crap. You
  can twist C99 all you want, but whenever p2-p1 is left to some undefined
  criteria of the compiler then it is just an absolute piece of crap. Period.
 You obviously never used segmented platforms (old DOS was such a thing,
 but there are others more recent, e.g. Cell with PowerPC is similar in this
 respect).

Yes I did work with those platforms. Remember the far qualifiers? Remember
what they were for? They were invented to make you, again, write something
wrong.

However, as parameters to functions, they were always in the same segment, so
the subtraction was always valid. C99 cannot back this up though, it was just
the way things were made back then. Maybe GCC inherited too much from those
days.


  On those it was valid only to sunstract pointers from each other
 when they pointed into the same segment.

Not really, you could always subtract. However, far pointers gave predictable
addresses, just like C99 says they pointer arithmetic should. Go and read C99
about the far qualifier so that you can see why it was not smart of you to
talk about DOS.

Still, on every segmented platform, the subtraction of the addresses of
parameters is always valid, as parameter will be all placed on the same stack.
And if some parameters had far qualifies and other not then the compilers
would warn you about it so that you could requalify them.

Don't talk about what you don't know, you clearly know much less about the old
days than me. Stick to C99.

  Because the pointer difference type
 was a 16 bit type, whereas the pointers could address 1MB of memory (hence 
 effectively 20 bit).  If you do the math you'll see that it's impossible
 to map all 2^20 possible differences between pointers (unsigned 2-completement
 20-bit arithmetic, otherwise 2^21 differences) into just 16 bit.  So yes,
 on those platforms it really was impossible to substract two arbitrary
 pointers.

No. Pointers of the same type, with the same qualifiers, were always
subtractable. Don't invent, it will just make you wrong. The addresses of
parameters on the stack would always be near (16-bit), so subtraction would
always be well-defined.

 C (the language) reflects such constraints.

Not really, no. Or can you back up your claims with an old standard applycable
30 or 40 years ago? I'm sure you can't. I don't even know if cdecl was well
defined back then, do you?

 With complete trust in your incapability to grok these concepts. but hats
 off to a capable troll,
 Michael.

Its is amazing how foast you take your self out and crash head-on into a wall.
And be proud of it. But you are right, this is fun. Keep on sending your
errors, inventions, inconsistencies, and mistakes, and I'll keep on correcting
them. Then you deflect and try to pretend that you said smart

[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #31 from rogerio at rilhas dot com  2010-08-12 18:32 ---
(In reply to comment #28)
 I built your test case with gcc and g++ without optimizations, and it worked
 fine.

Just like my script? I noticed that I'm using a not-the-newest GCC version, and
I know that some older version 3.xxx didn't have the problem (a few years ago).
Maybe it is something changed in the most recent versions?

  I could only get it to fail with gcc/g++ by optimizing, but then, I
 could get it to fail with MSVC by optimizing.  Seems to me, gcc and MSVC are
 doing the same thing, or you have some modified version of gcc that is not
 acting the same way as the official version.

I'm sorry, but I'm new to Linux, I'm not sure if the GCC I'm using got
tweaked in any way. It came with Ubuntu, but I don't know if it got upgraded
with Code::Blocks. I thought that -save-temps would provide you with that
information, didn't it? How can I get such information?

 Also, please provide an official spec for this cdecl you keep referring to.

Sorry, I did send you one in my variable arguments report and I forgot to send
it here olso. http://sco.com./developers/devspecs/abi386-4.pdf, see Figure
3-48: C Stack Frame. It is not a standard, as I'm sure you know, but it is a
well-defined concept.


-- 


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



[Bug c++/45265] GCC has an intermittent bug when computing the address of function parameters

2010-08-12 Thread rogerio at rilhas dot com


--- Comment #32 from rogerio at rilhas dot com  2010-08-12 18:38 ---
(In reply to comment #30)
 you can't even begin to understand how to make a temporary variable an 
 l-value.
 Please look up move constructors and rvalue references.  move constructors
 are not standard C++ code but the C++ standard committee decided to add rvalue
 references instead.  Please read the history of those and then come back when
 you understand what you are talking about.

If I were to follow your logic I would, because acording to your logic a
parameter doesn't have an address. But C99 doesn't limit this in any way, does
it? The  get the address of the item, period. So I don't need to go look up
unrelated topics, you are the one who should look up address of parameter.

function(class_name(initializer))

... should work if class_name(initializer) were an lvalue. One of you posted a
standard for that. Microsoft can get the address of class_name(initializer),
hence Microsft is capable of looking at class_name(initializer) as an l-value.
How Microsoft does it is not important, they do it and GCC doesn't. So
Microsoft can compile all these equivalently:

int a=10;
function(i)
function(int(20))
function(class_name(initializer))

I don't really care what GCC could do to make class_name(initializer) an
l-value, but if move constructors are a good way to go at it then do it. As
C99 doesn't specify this GCC is happy and doesn't need the feel to change. And,
so, I don't call it a bug, just a very nice feature that it is missing.


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #12 from rogerio at rilhas dot com  2010-08-11 11:20 ---
Created an attachment (id=21452)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21452action=view)
Preprocessed file (with example 2)


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #13 from rogerio at rilhas dot com  2010-08-11 11:21 ---
Created an attachment (id=21453)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21453action=view)
Source file (example 2)


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #14 from rogerio at rilhas dot com  2010-08-11 11:22 ---
No, you are not correct. The equivalent code to what I'm doing would be
something like:

int buffer[4]; // 16 bytes on stack
buffer[0]=(int)format
buffer[1]=(int)10
buffer[2]=(int)another_string
buffer[3]=(int)20
call format_direct

format_direct:
char** PTR4=(char**)buffer[0];
push PTR4
call format_indirect

format_indirect:
char** PTR4=get_from_stack  // gets PTR4 as pushed in format_direct
printf(%s %d %s %d,
PTR4[0],  // the same as (char*)buffer[0]
PTR4[1],  // the same as (int)buffer[1]
PTR4[2],  // the same as (char*)buffer[2]
PTR4[3]   // the same as (int)buffer[3]
);

This code must work, obviously. There is no undefined behaviour, it is correct
and portable code, and well defined and established. Even if the machine is 16
bits this would work without changes, just replace comment 16 bytes by 8
bytes and name PTR4 to PTR2, if you like the cosmetic changes.

I understand that when you look at your code you would call it undefined
behaviour, but your code is not the correct one: this one is. That is what I've
been trying to explain. The calling convention states that the parameters
should be packed ajdacent, like I did in the struct above, and not as you did
in your example, and getting the address of the parameter should get the
address of the start of the buffer, as I did manually.

Your code just ignored this and, of course, would not work (you don't even say
where you think the other parameters are). This is not an invention of mine, or
something that only works when I'm lucky, packing all parameters adjacent to
each other is something the compiler really needs to do, so if it gives me the
correct address of the first parameter then this code works *always* and is
very portable.

To show you that you are not correct I've done some changes to the source file,
where I created a new function format_direct2 that does something like this:

void format_direct2(char* dst_buffer, int dst_buffer_size_bytes, const char*
format, ...) {
int buffer[3];
buffer[0]=(int)format;
buffer[1]=(int)__DATE__;
buffer[2]=(int)__TIME__;
format_indirect(dst_buffer, dst_buffer_size_bytes, (const
char**)buffer[0]);
}

The new code works always, of course, since I'm the one ensuring that the
parameters are adjacent, and I'm the one selecting the correct address to pass
to format_indirect. I am, in fact, manually generating the 2 requirements -
compliance with the calling convention and passing the correct address to
format_indirect. It also works with GCC, of course, even when optimized (as
expected) and I attach the corresponding files. So, when optimized, you get
format_direct2 to work correctly and format_direct causes a segmentation
fault (and it shouldn't).

It would sure be interesting to see if you could quote some standard for C
which says that I'm not allowed to do this!!! I simply don't believe you can
find such text, or have I been wrong about C all my life and I can't use
pointers to navigate through buffers?? :-)


-- 

rogerio at rilhas dot com changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #18 from rogerio at rilhas dot com  2010-08-11 13:11 ---
Of course vsnprintf was my first choice, as you can see from the WIN32 part of
the code I sent you. In WIN32 I can use vsnprint in a very natural and
predictable way in format_indirect. In LINUX this cannot be used in
format_indirect as GCC does not allow me to use vsnprintf on a function that
doesn't take variable parameters. I tried to bypass it specifying variable
parameters for format_indirect, but of course the results are wrong because
GCC will have placed the wrong address in format_address inside
format_indirect. So, in fact, vsnprintf will have exactly the same problem as
I had, and I would report exactly the same bug like I did.

As you can see I've tried very hard to explain all details of the problem, and 
why this is a bug in GCC.

You just keep dismissing all my arguments without any justification whatsoever.
When you did justify I just proved your arguments to be false (no disrespect
intended) in the hope that this conversation would progress.

You don't explain why I can't rely on the calling convention to ensure the
parameters will be adjacent, and you don't explain why I can't use format to
get the address of that packed data on the stack. You just keep invoking some
standard where these 2 things are alledgedly not defined but without
materializing it (which I don't believe you can anyway!). You have not yet
shown why GCC is not required to place the parameters correctly on the stack,
and why GCC does not need to give me the true format.

So I'm stuck with your you can't because you can't replies and this
conversation will not progress any further, of course.

Best regards,
Rogerio


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #21 from rogerio at rilhas dot com  2010-08-11 17:04 ---
Subject: Re:  Indirect variable parameters sometimes cause
 segmentation fault

Yes, I was using that solution up to 2003, but then I stopped
using it in favour of the more confortable format (the one I
showed you) because it is less error-prone and easier to automate
(no need for the va_list declaration, start, and end). My teams
usually have a lot of rookies (we have schollarship programs)
and bugs would popup a lot (like switching the order of
parameters, for example).

I could go back to using it, of course, but I already have a lot
of code done with this format method, and it is not convenient
for me to go back and change anything in old code.

Anyway, I seem to have found a workaround for this problem
in GCC: it seems that if I use the format before calling the
format_indirect then there will be no problem (still to conform).

void format_direct(char* dst_buffer, int dst_buffer_size_bytes, const 
char* format, ...) {
const char** format_address=format;
format_indirect(dst_buffer, dst_buffer_size_bytes, format_address);
}

If I confirm this then this problem would no longer be blocking
and I would be able to live with it by creating a special macro
in Linux to use the format before calling format_indirect:

#define GCC_SPECIFIC_ADDRESS_OF(format) const char** format_address(format)

void format_direct(char* dst_buffer, int dst_buffer_size_bytes, const 
char* format, ...) {
format_indirect(dst_buffer, dst_buffer_size_bytes, 
GCC_SPECIFIC_ADDRESS_OF(format));
}

... or something along these lines. Maybe I should also replace const
char** by some other GCC-specificy defined type (that would have
no effect on Windows) just to get compilation errors where people try
to pass format directly whitout using the macro.

matz at gcc dot gnu dot org wrote:
 --- Comment #20 from matz at gcc dot gnu dot org  2010-08-11 16:10 ---
 A conforming variant of what you probably are trying to code is:
 
 #include stdio.h
 #include stdarg.h

 void format_indirect(char* dst_buffer, size_t dst_buffer_size_bytes,
  const char *format, va_list va)
 {
 vsnprintf(dst_buffer, dst_buffer_size_bytes, format, va);
 dst_buffer[dst_buffer_size_bytes-1]=0;
 }

 void format_direct(char* dst_buffer, size_t dst_buffer_size_bytes,
const char* format, ...)
 {
 va_list va;
 va_start (va, format);
 format_indirect(dst_buffer, dst_buffer_size_bytes, format, va);
 va_end (va);
 }

 int main(void)
 {
 char buffer[1000];
 format_direct((char*)buffer, sizeof(buffer), %s %s, __DATE__, __TIME__);
 printf(Result: \%s\\n, buffer);
 return 0;
 }
 ---

 Note how the va_list is constructed in the function that actually is
 a varargs one, in particular how the necessary parameter is mentioned.
 Note further how that va_list is passsed to the function that is not
 varargs in order to capture all variable arguments of its caller.

 There, no assumption on stack-layout.  It will work with all types and
 ABIs, even those that happen to pass even some varargs in registers,
 not on the stack.


   


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #22 from rogerio at rilhas dot com  2010-08-11 17:15 ---
(In reply to comment #19)
 (In reply to comment #18)
  Of course vsnprintf was my first choice, as you can see from the WIN32 part 
  of
  the code I sent you. In WIN32 I can use vsnprint in a very natural and
  predictable way in format_indirect. In LINUX this cannot be used in
 It's Linux (or GNU/Linux) not LINUX.

It is probably Win32, not WIN32. But thanks for the info.

  format_indirect as GCC does not allow me to use vsnprintf on a function 
  that
  doesn't take variable parameters. 
 I explained why, see 7.15 in the C99 standard.


didn't need your explanations, I already knew it. That just shows you have been
missing the point from the start. I told why I didn't use vsnprintf, but you
seem to have missed it. Note that if I didn't need format_indirect to do the
actual work then I wouldn't have found any bug in GCC.

Maybe you are not realizing that format_indirect will not actually use
vanprintf, and will, instead, use my own parsing routines for several types of
parameters. The reason why I need a format_indirect is because I may have users
of my modules who are the ones that receive the variables parameters, and must
then pass the work on to my format_indirect to do the actual work.


  I tried to bypass it specifying variable
  parameters for format_indirect, but of course the results are wrong 
  because
  GCC will have placed the wrong address in format_address inside
  format_indirect. So, in fact, vsnprintf will have exactly the same 
  problem as
  I had, and I would report exactly the same bug like I did.
 Not if you use it correctly, which you are not doing.
 void format_direct3(char* dst_buffer, int dst_buffer_size_bytes, const char*
 format, ...) {
 va_list va;
 va_start(va, format);
 vsnprintf(dst_buffer, dst_buffer_size_bytes, format, va);
 va_end(va);
 }


You missed the point again. I don't have any problem with any of the
format_direct functions if they were to do the actual formatting work. But they
are not. Many of our older software uses specific parameter parsing, so we
developed functions over the years to parse format strings ourselves with
specific parsing instructions. To reuse code as much as possible the work is
done in a format_indirect function that can be called by any of the several
format_direct functions.

If I could use format_direct I would have no problem and the GCC bug would not
bug me at all. But that would mean copying and maintainig our special
functionality which currently resides in one format_indirect function in
several (maybe dozens) of diferent format_direct functions.

You must have noted that I used va_start/va_end in my WIN32 example, so you
must be aware that I know how to use it. You must also be aware that in the
*Linux* :-) version I used snprintf instead, so you must have realized that I
already knew that I could not use va_start/va_end in the format_indirect
function.

Microsoft's compiler developers didn't see the need to limit use of
va_start/va_end inside format_indirect, so I was able to use it without any
problem. I tried it in GCC anyway but to no avail. I understood it and moved
on, you were the one to bring vsnprintf as a solution to format_indirect which
I pointed out to you was not a solution (the GCC bug persists). However, now
you know that the actual work is not done by vsnprintf.



  As you can see I've tried very hard to explain all details of the problem, 
  and 
  why this is a bug in GCC.
 GCC claims to support C and C++.  Can you point to part of either standard
 which says your code is valid?


Yes, sure. Or, at least, I can get close enough since I'm not interested in
really making you believe that GCC would be a better product if it didn't mess
up the pair of requirements I mentioned before. I'll just leave you to believe
whatever you like.

The first thing to note is that GCC doesn't only claim to be a C/C++ compiler:
it claims it can produce cdecl calls. So I will have to go a little outside of
the scope of C99.

The GCC manual http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc.pdf; describes the
usage of cdecl as a possible option. Although not present in the code I sent
you I tried cdecl and stdcall specifiers and GCC didn't change anything in the
compiled code. This is the first suspicion that GCC is not conforming to what
it was supposed to do.

If GCC supports cdecl on a x86 plaform then it must support the packing of
parameters as defined for x86 (it is not standardize that I know of, but it is
well defined). I sugest reading
http://en.wikipedia.org/wiki/X86_calling_conventions for a number of references
on this parameter packing in the stack, one of my favorites is
http://sco.com./developers/devspecs/abi386-4.pdf; where you can read in
Figure 3-48: C Stack Frame how the parameters should be placed on the stack.
GCC would only be cdecl-compliant if it were to conform to this specification
(I believe it does, I believe

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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #25 from rogerio at rilhas dot com  2010-08-11 19:51 ---
(In reply to comment #24)
 (In reply to comment #22)
  
  If GCC supports cdecl on a x86 plaform then it must support the packing of
  parameters as defined for x86 (it is not standardize that I know of, but it 
  is
  well defined). I sugest reading
  http://en.wikipedia.org/wiki/X86_calling_conventions for a number of 
  references
  on this parameter packing in the stack, one of my favorites is
  http://sco.com./developers/devspecs/abi386-4.pdf; where you can read in
  Figure 3-48: C Stack Frame how the parameters should be placed on the 
  stack.
 That's a good reference. Did you see page 70?
 If you're not interested in writing portable code, don't blame the compiler.
  Anyway, that enough for me, I already spent way too much energy and time 
 At least we can agree on that.

The reason for the reference of page 70 is exactly because of compilers like
GCC which claim to be cdecl compliant and are not. If GCC would do what it
claims to do and be cdecl compliant I would not blame the compiler and my code
(and code from many others) would be portable.

In other words my code is not portable because GCC is not doing what it should.
GCC causes code not to be portable a lot of times, like in the following case
(which does not compile because of GCC's shortcommings):

class Temp {
public:
Temp(int b);
Temp(Temp t);
void operator=(Temp t);
};

void func(int a, class Temp b, int c);

func(10, Temp(20), 30); // error

This code does not compile in GCC, and so is not portable. That's shortcomming
of GCC that makes my code be not portable, not me. Its GCC's fault that code
that invokes Temp(20) as a parameter is not portable, not the programmer's
fault.

Unfortunately, conversations like this one show that GCC will never be perfect,
because people like you will insist that the compiler doesn't need to do what I
said it should (even when facing the obvious references that I've posted), and
prove that page 70 is right about warning programmers not to rely on compilers
to do correct parameter placements.

My personal experience is that GCC is the cause for such portability problems.
You still insist that GCC doesn't need to improve in this respect, and that
shows why GCC will never be as good as other compilers. Microsoft, for example,
appreciates comments like mine because it helps them improve the product, but
you just want to dismiss it as bad code on my part. I know Microsoft's people
get paid to do so, but, still, I'm talking about the right mind set.

Note that you have not stated why you think my reply #22 is wrong, and I'm
pretty sure that's because you can't. All my arguments are solidly backed up,
but you just looked at page 70, interpreted it incorrectly (because you didn't
realize that compilers like GCC are the ones responsible for that remark), and
didn't bother to see that I'm right about my arguments. You just say that I
can't do it, but I have shown why I should be able to do it. You just dismissed
it, I think is a loss for GCC, but whatever.


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #27 from rogerio at rilhas dot com  2010-08-11 20:04 ---
(In reply to comment #26)
 This code does not compile in GCC, and so is not portable.
 No it is not portable because that code is just plain invalid; though MS
 accepts it as it is implementing something called move constructor as an
 extension.

I already told you you can't because you can't (or in this case is plain
invalid) is not an answer. Please explain concisely:

a) If GCC is cdecl compliant should it put the parameters on the stack as the
figure 3-48 shows? Can you quote any standard that there is any exception that
GCC can take advantage of and still claim to be cdecl-compliant?

b) When I code format shouldn't GCC give me the address of the format
parameter on the stack? Can you quote any standard that shows that the quote I
shoewd you of C99 has an exception anywhere that is applicable to this case?

Both in a) and b) the answer should be yes. A good non-buggy compiler will do
both things a)+b), as Microsoft does (without any extension).

If GCC can be made to do a)+b) simultaneously then don't worry about the
portability of my code because I just need a)+b) together and I will have no
problem, just leave the rest to me and don't you worry.

I think it would settle the issue if you could just simply answer these 2
questions a) and b) directly and clearly.


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #28 from rogerio at rilhas dot com  2010-08-11 20:07 ---
(In reply to comment #23)
 First off I already mentioned what is undefined in this example in comment 
 #11.
  The part of the standard that mentions about arrays.  And how the address of 
 a
 scalar is considered an array of size 1.  I don't have the standard in front 
 of
 me right now but those are what I remember from the standard.


Right. And I clearly explained in my comment #14 why you were wrong. Getting
back to comment #11 so that we can run around in circles brings no improvement
to this conversation, and you will just keep on being wrong, even if you had
the standard in front of you, because your example in comment #11 does not
correspond to the code I'm doing. My comment #14 explains what is the correct
code for comparison.


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #30 from rogerio at rilhas dot com  2010-08-11 20:58 ---
Really? Your comment #11 has so many mistakes in it that maybe you are the one
who should learn a little bit more on C.

The ABI is not of concern here really.  The issue comes down to you have:
char *a;
char **b = a;
use(b[1]);

This comment just means you missed the point. Maybe you just memorized the C
standar, maybe not, but you didn't understand that I was doing something
different. Did you miss the part in my comment #14 where I mentioned that a
does not point to only 4 bytes but, instead, 16 bytes? Didn«t you understand
the equivalent code would be:

char* a[4];
char **b =a[0];
use(b[1]);

Didn't you realize that there is nothing wrong with this code? Its basic C. The
code does not work because GCC is not doing its job right, otherwise, by cdecl
definition, there would a would be an array of 4 pointers, like I showed. It
seems you didn't understand, but it is, in fact, quite simple. Check what cdecl
means, then you will realize that the 4 parameters are supposed to be
equivalent to char* a[4]. Nothing else I can do here, really, if you don«t
understand this then maybe you should be responsible for answering to comments
on such an important project as GCC.

It is undefined what happens when you access b[1].  It does not matter if the
ABI defines that the arguments are passed via the stack in ascending order or
not.  It could pass them via descending order.  Accessing an out of bounds
array is causing the issue here.

This is very wrong again. Don«t hide in out of bounds array. The point is
exactly that, you are wrong about what the problem is. The problem is that the
address GCC gives me is not to the 4 packed parameters, not the out of bounds.
If GCC packed the 4 entries there would be no out of bounds problem. Maybe you
need to learn C, I did learn it and well, so I know what a pointer does and
what happens when you go out of bounds. So the problem is the underlying buffer
of data created by GCC is bad, not that I use the 1-entry pointer to an array
to access the following elements. You are just wrong, and I seem to be unable
to make you see just how wrong you are.

This is not about GCC vs MS Visual studio issue, this is a C/C++ standard issue
saying what you are doing is undefined.

Can you quote some part of the standard to back up your claims? I did backup my
claims, you have not yet backed up yours.

Another thing well defined in C is what happens when navigating an array out of
its bounds.

Kinda, you can go one past the array bounds for the address but you cannot
access it.  That is what the C/C++ standard says.  I can quote the standard if
needed.  Anything else is undefined.

You are just wrong again.

char* a[4];
char** b=a[0];
access(b[0], b[1], b[2], b[3]).

This code is valid although b is a pointer to one and only one address. This is
the example in my code (assuming cdecl), you can try to avoid it, and compare
to wrong code like you did in comment #11, but that will not be helpful to the
GCC project, you will just keep wasting resources.

So, as you can see, there is nothing correct about your comment #11. Should't
you be reading something somewhere then?


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #32 from rogerio at rilhas dot com  2010-08-11 21:12 ---
(In reply to comment #31)
 Didn't you understand the equivalent code would be:
 No, as the variables act the same if they are automatic variables or 
 arguments.
  there is no different between the two.  That has been my point from the
 beginning.

Wrong again. The cdecl definition is for parameters, there is no such thing for
automatic variables. So I can expect a given packing of arguments in a
cdecl-compliant compiler, and I can expect no such thing from automatic
variables.

Can you backup your claim? (I'm not really interested, just to let you know
that you missed a critical aspect again)


 I think it is time for me to end my part and say please follow up to the C
 standards news group as we are going in circles as a misunderstanding about 
 ABI
 and how arguments are passed have no concern to what the C standard says about
 variables (automatic and arguments) and the size of an array for an address of
 one.

Yes, I agree that is better as you don't backup anything you say. You didn't
even bother to answer to a) and b) of my comment 27 (and you woldn't,
obviously, as you dismiss cdecl as an important part to this discussion). I can
only assume that that is because you simply can't, since you so cleverly
avoided answering the questions I placed there which would surely settle the
matter.

Anyway, I found a workaround that makes GCC behave properly so I got my code
running again. So you can leave the bug as is and it won't bother me anymore.


-- 

rogerio at rilhas dot com changed:

   What|Removed |Added

   Severity|blocker |normal


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- 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

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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #38 from rogerio at rilhas dot com  2010-08-11 22:35 ---
(In reply to comment #34)
 (In reply to comment #25)
  In other words my code is not portable because GCC is not doing what it 
  should.
  GCC causes code not to be portable a lot of times, like in the following 
  case
  (which does not compile because of GCC's shortcommings):
  
  class Temp {
  public:
  Temp(int b);
  Temp(Temp t);
  void operator=(Temp t);
  };
  
  void func(int a, class Temp b, int c);
  
  func(10, Temp(20), 30); // error
 ISO/IEC 14882:2003(E) 8.5.3 [dcl.init.ref] paragraph 5

Thanks for this. I didn't know why GCC was unable to compile such code and now
I know: GCC is unable to convert a initialization passed as parameter to an
lvalue. Microsoft's compiler does know how to do that - there is no problem in
getting the address of such temporary variables, right? Oh, wrong, GCC can't,
that's just too hard on the poor thing.

... oh well, let's just not call that a portability issue created by GCC,
because no one explained to its developers how to get the address of a
temporary variable. Let's just not initialize temporary variables and stick to
the lowest common denominator, which is GCC.

Really?? Was that rally the explanation you wanted to provide??? I think its
just embarassing. Note that I didn't open a bug for this issue because I can,
in fact, reduce to the lowest common denominator. So, I can live without
(although not as confortably).

  This code does not compile in GCC, and so is not portable. That's 
  shortcomming
  of GCC that makes my code be not portable, not me. Its GCC's fault that code
  that invokes Temp(20) as a parameter is not portable, not the programmer's
  fault.
 ibid.
  Unfortunately, conversations like this one show that GCC will never be 
  perfect,
  because people like you will insist that the compiler doesn't need to do 
  what I
  said it should (even when facing the obvious references that I've posted), 
  and
  prove that page 70 is right about warning programmers not to rely on 
  compilers
  to do correct parameter placements.
 What a charming idea, that a compiler could become perfect by doing what I
 said it should

You must have missed something in the discussion because you failed to see that
what I say is what C99+cdecl say. Please forgive me for cutting sentences
short, I didn't think anyone would start making comments without reading the
whole conversation, my bad.

... is it still a charming idea after you read all the backups to my claims?


  My personal experience is that GCC is the cause for such portability 
  problems.
  You still insist that GCC doesn't need to improve in this respect, and that
  shows why GCC will never be as good as other compilers. Microsoft, for 
  example,
  appreciates comments like mine because it helps them improve the product, 
  but
  you just want to dismiss it as bad code on my part. I know Microsoft's 
  people
  get paid to do so, but, still, I'm talking about the right mind set.
 Oh, how delightfully quaint!


It is, isn't it? And it makes sense too, doesn't it? I bet that thinking that
GCC needs not improve on the stuff I commented here is a sure way to get you
there fast. I'm sorry I even tried!


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #39 from rogerio at rilhas dot com  2010-08-11 22:37 ---
(In reply to comment #37)
 Btw, 6.5.6/7 For the purposes of these operators, a pointer to an object that
 is
 not an element of an array behaves the same as a pointer to the first element
 of an array of length one with the type of the object as its element type.

No problem, as long as it doesn't make a copy. I clearly stated this, and
explained with C99, that even 1-entry arrays can be navigated beyond the
boundaries. I thoroughly explained the arithmetic. Where did you read that
1-entry arrays can be copied to a different location when someone requests the
address operator?


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #41 from rogerio at rilhas dot com  2010-08-11 22:50 ---
 It doesn't make it an array in the C sense.

What is an array in the C sense? Isn't it a sequence of entries? Is there any
other concept to go along with it that allows PTR4 to be set to any other value
than X? If so, where did you read it? I read in C99 that a pointer is simply a
variable that contains an address, and that C doesn't navigate arrays in the C
sense in anyway diferently than with simple pointers. Do you have a C99
section that shows a distinction significant to this issue?

 X gives you an address of X which happens to be on the stack.  Following
 parameters happen to be in adjacent stack slots.  Still C does not give
 you a way to access adjacent parameters by doing pointer arithmetic on
 X.

Can you explain then how X gets the format parameter from the stack and X[1]
doesn't get the next adjacent entry on the stack? Note that C99 is pretty clear
about the fact that X[1] will access bytes 4 to 7 after X. Can you backup your
claim with C99 or any other reference besides your personal interpretation?

 X does _not_ get you access to anything like a stack as there is
 no such concept in the C language.

No problem. I don«t want PTR4 to be a specific pointer to stack, I want it to
be a general pointer to memory. I don«t need more than that and C99 says I
should be able to get such generic address to PTR4 and dereference it. Where
can it be read that to access stack address space I should need a special
pointer? Where does it read I cannot derreference PTR4 if it points to stack?
Where can it be read that if I dereference PTR4 while its is pointing to stack
that pointer arithmetic will not be the same as any other?

  In
 foo (int x, int y, int z)
 there are only x, y and z.  There is no array of parameters, the only
 arrays are that of implicit size 1 at locations x, y and z which
 allows you to compute x + 1 (but not dereference that pointer).

No, cdecl states that x+1==y, and that x+2==z. If a compiler is
cdecl-compliant I can trust this to be true.


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #42 from rogerio at rilhas dot com  2010-08-11 22:51 ---
 It doesn't make it an array in the C sense.

What is an array in the C sense? Isn't it a sequence of entries? Is there any
other concept to go along with it that allows PTR4 to be set to any other value
than X? If so, where did you read it? I read in C99 that a pointer is simply a
variable that contains an address, and that C doesn't navigate arrays in the C
sense in anyway diferently than with simple pointers. Do you have a C99
section that shows a distinction significant to this issue?

 X gives you an address of X which happens to be on the stack.  Following
 parameters happen to be in adjacent stack slots.  Still C does not give
 you a way to access adjacent parameters by doing pointer arithmetic on
 X.

Can you explain then how X gets the format parameter from the stack and X[1]
doesn't get the next adjacent entry on the stack? Note that C99 is pretty clear
about the fact that X[1] will access bytes 4 to 7 after X. Can you backup your
claim with C99 or any other reference besides your personal interpretation?

 X does _not_ get you access to anything like a stack as there is
 no such concept in the C language.

No problem. I don«t want PTR4 to be a specific pointer to stack, I want it to
be a general pointer to memory. I don«t need more than that and C99 says I
should be able to get such generic address to PTR4 and dereference it. Where
can it be read that to access stack address space I should need a special
pointer? Where does it read I cannot derreference PTR4 if it points to stack?
Where can it be read that if I dereference PTR4 while its is pointing to stack
that pointer arithmetic will not be the same as any other?

  In
 foo (int x, int y, int z)
 there are only x, y and z.  There is no array of parameters, the only
 arrays are that of implicit size 1 at locations x, y and z which
 allows you to compute x + 1 (but not dereference that pointer).

No, cdecl states that x+1==y, and that x+2==z. If a compiler is
cdecl-compliant I can trust this to be true.


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #43 from rogerio at rilhas dot com  2010-08-11 22:52 ---
 It doesn't make it an array in the C sense.

What is an array in the C sense? Isn't it a sequence of entries? Is there any
other concept to go along with it that allows PTR4 to be set to any other value
than X? If so, where did you read it? I read in C99 that a pointer is simply a
variable that contains an address, and that C doesn't navigate arrays in the C
sense in anyway diferently than with simple pointers. Do you have a C99
section that shows a distinction significant to this issue?

 X gives you an address of X which happens to be on the stack.  Following
 parameters happen to be in adjacent stack slots.  Still C does not give
 you a way to access adjacent parameters by doing pointer arithmetic on
 X.

Can you explain then how X gets the format parameter from the stack and X[1]
doesn't get the next adjacent entry on the stack? Note that C99 is pretty clear
about the fact that X[1] will access bytes 4 to 7 after X. Can you backup your
claim with C99 or any other reference besides your personal interpretation?

 X does _not_ get you access to anything like a stack as there is
 no such concept in the C language.

No problem. I don«t want PTR4 to be a specific pointer to stack, I want it to
be a general pointer to memory. I don«t need more than that and C99 says I
should be able to get such generic address to PTR4 and dereference it. Where
can it be read that to access stack address space I should need a special
pointer? Where does it read I cannot derreference PTR4 if it points to stack?
Where can it be read that if I dereference PTR4 while its is pointing to stack
that pointer arithmetic will not be the same as any other?

  In
 foo (int x, int y, int z)
 there are only x, y and z.  There is no array of parameters, the only
 arrays are that of implicit size 1 at locations x, y and z which
 allows you to compute x + 1 (but not dereference that pointer).

No, cdecl states that x+1==y, and that x+2==z. If a compiler is
cdecl-compliant I can trust this to be true.


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #44 from rogerio at rilhas dot com  2010-08-11 22:53 ---
(In reply to comment #36)
 (In reply to comment #35)
  (In reply to comment #33)



 It doesn't make it an array in the C sense.

What is an array in the C sense? Isn't it a sequence of entries? Is there any
other concept to go along with it that allows PTR4 to be set to any other value
than X? If so, where did you read it? I read in C99 that a pointer is simply a
variable that contains an address, and that C doesn't navigate arrays in the C
sense in anyway diferently than with simple pointers. Do you have a C99
section that shows a distinction significant to this issue?

 X gives you an address of X which happens to be on the stack.  Following
 parameters happen to be in adjacent stack slots.  Still C does not give
 you a way to access adjacent parameters by doing pointer arithmetic on
 X.

Can you explain then how X gets the format parameter from the stack and X[1]
doesn't get the next adjacent entry on the stack? Note that C99 is pretty clear
about the fact that X[1] will access bytes 4 to 7 after X. Can you backup your
claim with C99 or any other reference besides your personal interpretation?

 X does _not_ get you access to anything like a stack as there is
 no such concept in the C language.

No problem. I don«t want PTR4 to be a specific pointer to stack, I want it to
be a general pointer to memory. I don«t need more than that and C99 says I
should be able to get such generic address to PTR4 and dereference it. Where
can it be read that to access stack address space I should need a special
pointer? Where does it read I cannot derreference PTR4 if it points to stack?
Where can it be read that if I dereference PTR4 while its is pointing to stack
that pointer arithmetic will not be the same as any other?

  In
 foo (int x, int y, int z)
 there are only x, y and z.  There is no array of parameters, the only
 arrays are that of implicit size 1 at locations x, y and z which
 allows you to compute x + 1 (but not dereference that pointer).

No, cdecl states that x+1==y, and that x+2==z. If a compiler is
cdecl-compliant I can trust this to be true.

(sorry for the dupplication, I'm getting a lot of collisions)


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #45 from rogerio at rilhas dot com  2010-08-11 22:54 ---
(In reply to comment #43)

(please disregard this duplication)


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #46 from rogerio at rilhas dot com  2010-08-11 22:54 ---
(In reply to comment #42)

(please disregard this duplication)


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #47 from rogerio at rilhas dot com  2010-08-11 22:55 ---
(In reply to comment #41)

(please disregard this duplication)


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #49 from rogerio at rilhas dot com  2010-08-11 23:22 ---
(In reply to comment #40)
 (In reply to comment #39)
  (In reply to comment #37)

 Why do you think GCC makes it the address of a copy?

Well, the first observation was dumpung the memory around the returned address
to see that the other parameters were not there.

The second observation was to see that the original object pushed by the caller
of direct_format was writen to an address which was not the one obtained in
format_indirect.

Both are strong indicators. The first because I see the disassembly showing a
sequence of pushes for all parameters (hence, knowing x86, I trust they will be
adjacent although I can't check individual movements because I was unable to
trace individual assenbly instructions, but I checked the stack address after
the pushes and they are all sequential in memory). These parameters are never
changed in the stack, and keep adjacent all the time. So, accessing
format_address should reveal them.

The second is very difficult to observe in compiled code because any access to
format before passing it as a parameter to format_indirect seems to fix
the problem (this is the basis for my workaround). However, I was able to
hardcode some printf's to locations where I knew the variables would be and
observe the results: the pushed parameters are kept adjacent, but the
address_format is somewhere else. My guess is that it is pointing to the rom
address where the string is stored in the executable, but I cannot be sure.


 You are wrong here.  The next paragraph, 6.5.6/8, explains that,
 ... otherwise the behavior is undefined.  If the result points one past
 the last element of the array object, it shall not be used as the operator
 of a unary * operator that is evaluated..  Where I point you to
 6.5.3.2/3 if you now claim that x[2] isn't invoking the unary * operator.

You are the ones saying that char** format_address is equivalent to a 1-entry
array. I have stated often that the array to which PTR4 points is an array of 4
entries, backed by cdecl.

But if your interpretation is that access to X+4 fails because the behaviour is
undefined because GCC generates code as that for a 1-entry array at address X,
and then generates some code to make accesses to address X+4 or X+8 (and so on)
fail, then no problem: just have GCC return the correct address X and I'll do
the accesses in assembly where I can trust what happens when I access X+4.

Note that your argument (of undefined behaviour) is only valid for declared
arrays, which I still think is not the case here. Or, at least, it points to a
4-entry array.

Also note that your argument does not backup the claim why GCC can return a
wrong address for format. I also believe that you know that if GCC did return
the original address X on the stack then the undefined behaviour of [X+1]
would be to return the 4 bytes at X+4 without any problem, right? Or does GCC
generate specific code to make this memory access fail?


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #50 from rogerio at rilhas dot com  2010-08-11 23:43 ---
(In reply to comment #48)
 No, cdecl states that x+1==y, and that x+2==z.
 Maybe the ABI says that but that does not mean you can access x + 1 to get
 to y at least in a standard defined way.  That is the whole point of it
 acting as it was an array of size 1.

Please note what you are saying. You mean that if, under GCC, I write some code
like:

void func_anything(void) {
char** PTR4=random_anywhere_in_valid_user_space_including_stack();
char* a=PTR4[0];
char* b=PTR4[1];
char* c=PTR4[2];
char* d=PTR4[3];
}

Are you telling me that GCC will not generate code to get propper values for
b, c, and d because reading past a is undefined? Note that the random
function does not define an array in the C sense, it just returns a pointer
no different than format_address.

The randomizer could, in fact, by something like
my_malloc_hand_crafted_with_no_relation_to_malloc_and_allocating_memory_directly_from_the_os()...
are you saying I would not be able to predictably access any of its bytes
(since it would not be related to an array of bytes in the C sense?

Now instead of a randomizer or a my_malloc I just called
get_random_address_exclusivelly_in_stack_space(), would access fail then?

And if instead I just called:

func foo(int x, int y, int z) {
int* PTR4=get_random_address_from_triplet(x, y, z);
int new_var=*PTR4;
}

Would it fail here for new_var? If not, I could just write something like:

func foo(int x, int y, int z) {
int* PTR4_x=get_random_address_from_triplet_but_make_sure_its_x(x, y, z);
int new_x=*PTR4_x;
int* PTR4_y=get_random_address_from_triplet_but_make_sure_its_y(x, y, z);
int new_y=*PTR4_y;
int* PTR4_z=get_random_address_from_triplet_but_make_sure_its_z(x, y, z);
int new_z=*PTR4_z;
}

Would this work? I'm not sure where this conversation is going to, but if this
code worked I could be a pretty good workaround for my indirect format. It must
work, right, I don't know which part of C99 says is, but if it didn«t work then
GCC would be useless and we know it is not.

So, the only possible conclusion is that format_address does not behave as a
1-entry array, because all these examples would lead to undefined results, and
so it must, in the very least, correspond to a 4-entry array (because I know I
can read the RAM locations with code generated by GCC).


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #51 from rogerio at rilhas dot com  2010-08-12 02:08 ---
Given all that we have established in our conversation I think I can now
demonstrate the bug easily.

The entry to the format_direct call (in the main function, just before
entering the format_direct function) disassembles to this (using
Code::Blocks, I've added comments):

0x80484de   movDWORD PTR [esp+0x10],0x80485f0 // __TIME__
0x80484e6   movDWORD PTR [esp+0xc],0x80485f9 // __DATE__
0x80484ee   movDWORD PTR [esp+0x8],0x8048605 // format string
0x80484f6   movDWORD PTR [esp+0x4],0x3e8 // sizeof(buffer)
0x80484fe   leaeax,[ebp-0x3f0]
0x8048504   movDWORD PTR [esp],eax // buffer
0x8048507   call   0x8048460 format_direct(char*, int, char const*, ...)

At this point the $esp is 0xbfaeef00. So, the correct value for format (as
defined in C99) is:

esp+8 = 0xbfaeef08

Reading that memory address after the mov's I find 0x8048605 (format string).
The 0xbfaeef08 is the value I've been calling X and the value I will expect to
be passed to format_indirect.

Reading the following address (+4) I see 0x80485f9 (date), and reading the next
(+8) I see there 0x80485f0 (time). They are all packed together as expected by
the cdecl ABI. Snapshot-2 (which I will send you after this message) shows this
(after the mov's).

After entering format_direct, I inserted the line:

char buffer[1000]; buffer[0]=0;

Without this line the compiler generates correct code, but with it if manifests
the bug. Just before calling format_indirect, the disassembly is this (also
with comments):

0x804848d   leaeax,[ebp-0x3f8]
0x8048493   movDWORD PTR [esp+0x8],eax  // format
0x8048497   moveax,DWORD PTR [ebp+0xc]
0x804849a   movDWORD PTR [esp+0x4],eax  // dst_buffer_size_bytes
0x804849e   moveax,DWORD PTR [ebp-0x3f4]
0x80484a4   movDWORD PTR [esp],eax  // dst_buffer
0x80484a7   call   0x8048434 format_indirect(char*, int, char const**)

The $ebp contains 0xbfaeeef8, and so ebp+0x10 is 0xbfaeef08. That is the value
pushed onto the stack, and it is the correct format which I called X
(Snapshot-3).

Next, entering format_indirect (Snapshot-4), the disassembly is this:

0x804843a   moveax,DWORD PTR [ebp+0x10]
0x804843d   movDWORD PTR [ebp-0x4],eax
0x8048440   moveax,DWORD PTR [ebp-0x4]
0x8048443   moveax,DWORD PTR [eax]
0x8048445   movDWORD PTR [ebp-0x8],eax
0x8048448   moveax,DWORD PTR [ebp-0x4]
0x804844b   addeax,0x4
0x804844e   moveax,DWORD PTR [eax]
0x8048450   movDWORD PTR [ebp-0xc],eax
0x8048453   moveax,DWORD PTR [ebp-0x4]
0x8048456   addeax,0x8
0x8048459   moveax,DWORD PTR [eax]
0x804845b   movDWORD PTR [ebp-0x10],eax

Unfortunately I have a really hard time debugging in Linux and it took me
almost an hour of trial and error (in between breakpoints not working, dumps
not working, the debugger hanging, repeating all addresses and retyping this
message because each time I run things endup at diferent places in memory,
etc.) to get all this information in one run, but I could not get the last
memory dump to work and I will not repeat the process again.

Instead, maybe you can go all out and believe me that the format_address is
wrong, as the watch window shows. The PTR4 will contain a random value Y of
0xbfaeeb00 which has no relation to the correct address X of 0xbfaeef08.

In fact, the watch window shows what is around PTR4, which looks to me like a
rom string table for the executable. It also shows that PTR4[0] returns the
correct string, but that PTR4[1] does not. If PTR4 were 0xbfaeef08 (as it
should by the definition of  in C99), then PTR4[1] would return the correct
string __DATE__ (nothing undefined in GCC's code behavior if the address PTR4
is correctly returned as X, as the disassembly shows the machine will just
access memory addresses after X).

With my compilation script I could not reproduce the problem (I don't know all
the options Code::Blocks uses, and so I did not change my compilation script to
use the same options), but that should not be necessary as my original
attachments and compilation script manifest the problem.

Maybe this bug doesn't affect many people, but it is a bug, and it affects me
(and my team). Probably even worse than that, it shows GCC is not C99 compliant
in the  operator.

Also, I hope this demonstration shows how futile it is for all of you to try to
argue that the problem in my code's portability, or that format_address is
like an array of 1 entry, or even that accessing PTR4[1] is undefined (the
disassembly shows it is not, the pointer arithmetic and no boundary checking
defined in C99 are all good and applied in the generated code). I think it also
shows that maybe you should have believed me in the first place instead of just
dismissing my claims as forms of non-conformity. I still don't think this
should have

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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #52 from rogerio at rilhas dot com  2010-08-12 02:09 ---
Created an attachment (id=21462)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21462action=view)
Snapshot 1 - Breakpoint before calling format_direct


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #53 from rogerio at rilhas dot com  2010-08-12 02:10 ---
Created an attachment (id=21463)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21463action=view)
Snapshot 2 - Inside format_direct to show cdecl ABI parameter packing


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #54 from rogerio at rilhas dot com  2010-08-12 02:12 ---
Created an attachment (id=21464)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21464action=view)
Snapshot 3 - Breakpoint before calling format_indirect (showing dump for
$ebp+0x10)


-- 


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



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

2010-08-11 Thread rogerio at rilhas dot com


--- Comment #55 from rogerio at rilhas dot com  2010-08-12 02:12 ---
Created an attachment (id=21465)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21465action=view)
Snapshot 4 - Showing incorrect value for PTR4


-- 


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



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

2010-08-10 Thread rogerio at rilhas dot com
When using variable parameters indirectly (the variable-parameter function
calls another function to format its parameters giving it the original address
of the format string), the results are usually ok for non-optimized builds and
cause segmentation faults in optimized builds.

In a large project I also detected that unoptimized builds would cause
segmentation faults if the variable-parameter function declared a char buffer,
and would not fail if it declared an int buffer of the same total size. However
this is difficult to reproduce, so the test case I send you does not show this.

In the code I send you you can see main calling format_direct to format
some variable parameters, which in turn calls format_indirect to do the
actual work. This is a pattern I use a lot and for which I never had a problem
under Windows with any of Microsoft's Visual Studio versions (I'm fairly new to
LINUX, this is my first software port project).

If this test case is compiled with g++ -v -save-temps
gcc_bug_format_indirect.cpp -o gcc_bug_format_indirect.exe.ok then it works
ok, but if it is compiled with g++ -v -save-temps -O2
gcc_bug_format_indirect.cpp -o gcc_bug_format_indirect.exe.ko it causes a
segmentation fault (at least on my system it does, when it doesn't cause a
segmentation fault the results are just wrong).

I attach the preprocessed file, the source file, and the compilation script I
used.


-- 
   Summary: Indirect variable parameters sometimes cause
segmentation fault
   Product: gcc
   Version: 4.3.3
Status: UNCONFIRMED
  Severity: blocker
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: rogerio at rilhas dot com
 GCC build triplet: i686-virtualboxvm-ubuntu?
  GCC host triplet: i686-virtualboxvm-ubuntu?
GCC target triplet: i686-virtualboxvm-ubuntu?


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



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

2010-08-10 Thread rogerio at rilhas dot com


--- Comment #1 from rogerio at rilhas dot com  2010-08-10 22:03 ---
Created an attachment (id=21448)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21448action=view)
Preprocessed file


-- 


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



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

2010-08-10 Thread rogerio at rilhas dot com


--- Comment #2 from rogerio at rilhas dot com  2010-08-10 22:03 ---
Created an attachment (id=21449)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21449action=view)
Source file with comments


-- 


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



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

2010-08-10 Thread rogerio at rilhas dot com


--- Comment #3 from rogerio at rilhas dot com  2010-08-10 22:04 ---
Created an attachment (id=21450)
 -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21450action=view)
Compilation script (for the working and non-working builds)


-- 


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



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

2010-08-10 Thread rogerio at rilhas dot com


--- Comment #5 from rogerio at rilhas dot com  2010-08-10 22:33 ---
Are you sure this is the way to resolve this issue? I think this will make GCC
an inferior product, as all other compilers I've tested produce correct
results. As GCC sometimes produces correct code (and in such cases it works) I
don't see anyway to get around the fact that this is, in fact, a bug.

Additionally, I've sent you an example of how to compile it in a way that it
works when compiled with GCC. Furthermore, I think most people would expect it
to work as I'm passing the address of the original parameter. I've also shown
the code for Windows where I can then use a va, but there doesn't seem to exist
an equivalent for LINUX. Even if there were an equivalent this bug would affect
its behaviour too, as I've checked the memory contents and the format string
seems to have been copied and its original address on the stack is no longer
preserved, which, of course, is wrong.

If you still decide to discard this problem I will end up with no way to work
around it and will have to definitively abandon LINUX as a software platform
because of this shortcomming of GCC (which, I repeat, is not found on other
compilers).

Thanks,
Rogerio


-- 

rogerio at rilhas dot com changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |


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



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

2010-08-10 Thread rogerio at rilhas dot com


--- Comment #6 from rogerio at rilhas dot com  2010-08-10 22:35 ---
Let me just add: if you can tell me what options to set to make it always work
that would already be helpful. I noticed that disabling optimizations helps,
but not everytime (adding a lot of local automatic variables to the direct
function seems to have a negative effect sometimes).


-- 


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



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

2010-08-10 Thread rogerio at rilhas dot com


--- Comment #8 from rogerio at rilhas dot com  2010-08-11 00:54 ---
I think you are wrong, I'm not depending on undefined behaviour. When I request
format that is clearly defined: I should be getting the address of the format
pointer as placed on the stack. Just like I would when requesting the address
of an int parameter placed on the stack, I would get its stack address. If were
to write to that address I would write onto the stack. That is well defined.
Then, by another well defined attribute (the calling convention) I should be
able to navigate the stack to get the other parameters. There is no hack here!
It is all well defined. As long as the compiler doesn't mess it up and do
something undocummented or something that violates these well-defined
behaviours then everything is just fine. A compiler that doesn't verify both of
these 2 well-defined characteristics simultaneously has a bug.

I'm not coding for the Xbox nor for NT 3.5, but I assume that if I can get
Microsoft's compiler to use the calling convention that I want I will be able
to get the code to run. The reasoning is very simple: when I request
Microsoft's compilers something like format I get the stack address for the
format variable placed on the stack (as expected, not some copy unpredictably
placed somewhere else on the stack), and as Microsoft's compilers strictly
respect the calling conventions then I'm sure it would work. Microsoft's
compilers don't mess it up while optimizing. The only possibility for it not
to work would be for Microsoft's compiler not to let me select the calling
convention I wanted, which I seriously doubt.

To prove this I just compiled the code to Windows Mobile and it works just fine
on an ARM platform (my mobile phone), compiled with Visual Studio 2008, despite
the fact that it is a very diferent platform from x86. In fact, it is
conceptually very close to PowerPC, so I think this code would compile
correctly on PowerPC as well.

As I stated there is no undefined behaviour here, and I know exactly what I am
doing when I'm navigating the stack based on the address of the original format
string on the stack and on the calling convention used. That is what I would do
if programming in assembly language, so the compiler must not mess up these 2
well defined items.

So there is nothing wrong with my source, and it works everywhere I tried
except with GCC. From your comment I suspect I'm just wasting my time, because
you seem to be missing the point altogether. But of course I respect your
position of not fixing this (as I must, since I'm not the one working on
GCC!!).

I reopened the bug just to give you this last piece of information about the
Windows Mobile (no need to reply if you don't want to). Since you are very keen
on closing this report whithout backing your claims and clearly explaining how
come you say the behaviour is not defined I don't feel the interest to persue
this issue any further (especially because I feel it shouldn't be necessary for
me to explain all this, I think it should be fairly obvious to people
developing a compiler), so I will just drop LINUX for now (until I have the
oportunity to test other compilers).

Thanks for your attention anyway!


-- 

rogerio at rilhas dot com changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |


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



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

2010-08-10 Thread rogerio at rilhas dot com


--- Comment #10 from rogerio at rilhas dot com  2010-08-11 01:57 ---
I'm replying now not in the context of the bug (since as I mentioned I must
move on), but just as a conversation between 2 persons. So please don't getting
me wrong for insisting.

The cdecl calling convention on x86-32 machines says that for any function call
the arguments are placed on the stack as a series of 4-byte pushed values. I've
checked that GCC respects this convention when calling a function and not
optimized. So, for a typical GCC functiona call GCC pushes the parameters
correctly according to the cdecl calling convention:

func(a, b, c, d)

... the parameters will pushed right-to-left like:

push d (4-byte)
push c (4-byte)
push b (4-byte)
push a (4-byte)
call func

Obviously there are exceptions for doubles and structs, but this is not the
case here as char* and int are pushed exactly the same way, as 4-byte values.
This is well defined, right? The cdecl calling convention defines this clearly,
correct? Or does GCC somehow uses another calling convention?

Another thing well-defined in C is that when I request the address of a
variable I get the address of it. So, inside func, when I request a I get the
stack address where a was pushed to. This is also well defined, right?

Another thing well defined in C is what happens when navigating an array out of
its bounds. Unlinke what you say, the behaviour is deterministic in absolutely
every machine: if my PTR4 pointer to a 4-byte value contains the value X, then
PTR4[1] accesses address memory X+4. The same way, if my PTR2 points to a
2-byte value at address Y, then PTR2[1] will access address Y+2. There is no
hack here either, the behaviour is very well defined, and C doesn't care about
or check the bounds of the array.

So, if the calling convention states (in the example above) that b is placed
4 bytes after a, and that c is placed 4 bytes after b, and so on, it
follows, without any doubt, that if I get a PTR4 to point to a, and the
address of a on the stack is X, then PTR4[0] accesses a, PTR4[1] accesses
b, PTR4[2] accesses c, and so on. It doesn't mater the size of the array, C
will not check nor care about it, I can navigate the stack with it. That is
what I do with format_address, since it is a char** and char** has size 4 then
format_address is a PTR4. So, format_address[0] is a (or it should be if
format returned the true address of a), and *without any doubt or hack*
format_address[1] is b, and *with exactly the same confidence*,
format_address[2] is c, and so on. This is one of the most well established
bases in C, for several decades now, so there is really no arguing about it.

The problem is that GCC, when optimizing, places a somewhere on the stack
which is not contiguous to b. I think (although I'm not sure) that GCC does
something like this:

push d
push c
push b
push a
call format_direct

format_direct:
push some varied stuff
push [a copy of the original a again somewhere]
push [address of the above copy of a]
call format_indirect

format_indirect: (example)
mov eax,[address of the copy of a+0] // not the original a, but the copy
mov ebx,[address of the copy of a+4] // contains some varied stuff, not b

I'm not sure if GCC does exactly this, but I'm sure that, when optimizing, GCC
does not place a adjacent to b, and it should. Since I cannot get to b
I'm not sure if the same happens to c.

This clearly violates the calling convention. If the calling convention were
respected then a, b, c, and d would all be adjacent, so I could
navigate the 1-entry (4-byte) array using format_address[0], format_address[1],
format_address[2], and format_address[3]. I don't see how you can refute one of
the most well established properties of C, as the language allows me to
populate any memory buffer with whichever stuff and then navigate with a 4-byte
pointer (as long as properly aligned, which is the case here). I'm just doing
that with the stack, wich should be (by the calling convention) a 4-byte
aligned memory buffer with 4 adjacent 4-byte values abcd.

So, my point is: if - req1) GCC placed the parameters on the stack adjacent to
one another (as it should as a result of the selected calling convention) *AND*
- req2) if it gave me the address of the original format parameter on the stack
(as it should by the definition of getting the address of a function parameter)
then the code would work correctly, since - req3) is well established that C
does not perform array boundary checking and, thus, PTR4[1] accesses memory
location exactly 4 bytes after memory location PTR4[0].

Since I believe none of these 3 requirements is refutable, and since they are
all well established, then - bug1) GCC is not putting the parameters adjacent
on the stack as it should *OR* - bug2) GCC is not giving me the correct address
when I ask for format. The - bug3) of not doing pointer arithmetic correctly
because the array has size 1 (your argument) is simply not true, I checked it
while