Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: x86 Stack Confusion

Reply
Thread Tools

Re: x86 Stack Confusion

 
 
John Devereux
Guest
Posts: n/a
 
      01-09-2006
"Mark B" <(E-Mail Removed)> writes:

> "John Devereux" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>
> <snip>
>> Actually gcc for example will typically silently replace
>>
>> printf("Hello\n");
>>
>> with
>>
>> puts("Hello\n");

>
> Doubtful... those 2 lines are not equivalent.


So I see! I should have been either more accurate, or more vague.

gcc replaces calls to printf() with calls to puts()... when it thinks
it can.

I was trying to show by example that C compilers can indeed use
"compiler magic", in this case to call an entirely different function
from what was expected.

Perhaps this behaviour is not compatible with standard C, in which
case, I'm sorry for mentioning it!

--

John Devereux
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      01-10-2006
John Devereux <(E-Mail Removed)> writes:
> "Mark B" <(E-Mail Removed)> writes:
>> "John Devereux" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>> <snip>
>>> Actually gcc for example will typically silently replace
>>>
>>> printf("Hello\n");
>>>
>>> with
>>>
>>> puts("Hello\n");

>>
>> Doubtful... those 2 lines are not equivalent.

>
> So I see! I should have been either more accurate, or more vague.
>
> gcc replaces calls to printf() with calls to puts()... when it thinks
> it can.
>
> I was trying to show by example that C compilers can indeed use
> "compiler magic", in this case to call an entirely different function
> from what was expected.
>
> Perhaps this behaviour is not compatible with standard C, in which
> case, I'm sorry for mentioning it!


The behavior is perfectly compatible with standard C, as long as the
program produces the expected output. Compilers in general are free
to optimize code as long as all the side effects (including I/O) are
performed as required. Similarly, the compiler can replace a memcpy()
call with an assignment, as long as it does the same thing.

Note that this particular optimization depends on the compiler knowing
how printf() behaves. That's legitimate, since it's part of the
standard library. If you wrote your own function taking a variable
number and type of parameters, the compiler wouldn't be able to
perform the same kind of optimization (unless it can look into the
body of your function).

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      01-10-2006
Flash Gordon <(E-Mail Removed)> writes:
> jacob navia wrote:
>> John Devereux a écrit :
>>>
>>> Actually gcc for example will typically silently replace
>>> printf("Hello\n");
>>>
>>> with
>>>
>>> puts("Hello\n");
>>>
>>> This makes hello.c 3k long on my system. The compiler does interpret
>>> the format string, and uses the full printf where needed. This also
>>> allows it to catch errors where the parameters do not match the format
>>> string.

>> Replacing printf with puts can be only done when the return value
>> is not used, since puts returns "some nonnegative value" according to
>> the standard, not the number of characters written.

>
> If the implementation wants to do that replacement, it can make puts
> return the number of characters written, since in this universe the
> number of characters written will always be non-negative. I assume
> that gcc only makes this replacement on systems where it knows that
> this is the non-negative value that will be returned.


Yes, an implementation can do this. <OT>gcc can't, since it's just a
compiler, not a complete implementation; it uses the library provided
by the underlying system.</OT>

Of course, the result isn't used in the example given (assuming the
lines are intended to be complete statements and aren't preceded by
something like "result =".

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      01-10-2006
John Devereux wrote:
> "Mark B" <(E-Mail Removed)> writes:
>
>> "John Devereux" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>>
>> <snip>
>>> Actually gcc for example will typically silently replace
>>>
>>> printf("Hello\n");
>>>
>>> with
>>>
>>> puts("Hello\n");

>> Doubtful... those 2 lines are not equivalent.

>
> So I see! I should have been either more accurate, or more vague.


We all make mistakes, it's just that here you have a very high chance of
being called on them. A good thing IMHO.

> gcc replaces calls to printf() with calls to puts()... when it thinks
> it can.
>
> I was trying to show by example that C compilers can indeed use
> "compiler magic", in this case to call an entirely different function
> from what was expected.
>
> Perhaps this behaviour is not compatible with standard C, in which
> case, I'm sorry for mentioning it!


There is an oft quoted (here at least) "as if" rule. Basically, if as
far as a conforming program can tell everything is behaving "as if" the
implementation did what the standard says (calling printf when you use a
printf call in this case) then the implementation can do whatever it like.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      01-10-2006
jacob navia wrote:
> John Devereux a écrit :
> >
> > Actually gcc for example will typically silently replace
> >
> > printf("Hello\n");
> >
> > with
> >
> > [puts("Hello");]

>
> Replacing printf with puts can be only done when the return value
> is not used, ...


Not strictly true. A compiler could still replace the printf in...

if (printf("Hello\n") < 0)
fputs("error writing output\n", stderr);

--
Peter

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      01-10-2006
jacob navia wrote:
>
> If you re-read what I said, you will notice that I never said that
> "most compilers have things called _stdcall", but that they have
> "markers" to indicate the preferred calling convention. The _stdcall
> was just an example of a marker. Gcc uses other markers, and Borland
> yet another. There are compilers (definitely) with only ONE calling
> convention but most of them do have several, and they do use some
> syntax to allow the user to specify which one he/she prefers.


The marker used by C compilers is












(Yes, that was it. Go back and read it again, closely.)

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      01-10-2006
John Devereux wrote:

> "Mark B" <(E-Mail Removed)> writes:
>
>
>>"John Devereux" <(E-Mail Removed)> wrote in message
>>news:(E-Mail Removed)...
>>
>><snip>
>>
>>>Actually gcc for example will typically silently replace
>>>
>>> printf("Hello\n");
>>>
>>>with
>>>
>>> puts("Hello\n");

>>
>>Doubtful... those 2 lines are not equivalent.

>
>
> So I see! I should have been either more accurate, or more vague.
>
> gcc replaces calls to printf() with calls to puts()... when it thinks
> it can.
>
> I was trying to show by example that C compilers can indeed use
> "compiler magic", in this case to call an entirely different function
> from what was expected.
>
> Perhaps this behaviour is not compatible with standard C, in which
> case, I'm sorry for mentioning it!


The interesting point here is that prior to ANSI C, few
if any compilers could perform such optimizations. ANSI made
the Standard library function names off-limits for other uses,
and suddenly it became possible for the compiler to "know" that
printf() wasn't just J. Random Function but a function about
which it coult have built-in knowledge. Similar knowledge makes
it possible to compile sqrt() and memcpy() and various other
Standard library functions in-line.

What we lost in the exchange (TANSTAAFL) was the ability to
substitute user-defined replacements for the Standard library
functions: if you've got a more accurate inverse cosine, you
can't call it acos(). The place this becomes most irksome is
with malloc() and friends, where debugging could be enormously
improved if only we could insert our own instrumented versions.
Alas, the Standard forbids it on pain of undefined behavior.

--
Eric Sosman
(E-Mail Removed)lid

 
Reply With Quote
 
Dik T. Winter
Guest
Posts: n/a
 
      01-10-2006
In article <(E-Mail Removed)> Keith Thompson <(E-Mail Removed)> writes:
> (E-Mail Removed) (Dag-Erling Smørgrav) writes:
> > "osmium" <(E-Mail Removed)> writes:
> >> When a knowledgeable person says "C calling convention", *this* is
> >> what he means. There is nothing analogous to printf() with it's
> >> indeterminate number of parameters in, Pascal, for example.

> >
> > Yes, there is. Write() and WriteLn() both take a variable number of
> > arguments. There is however no way for the programmer to define a
> > procedure which takes a variable number of arguments.

>
> Yes, but as I recall the Write and WriteLn procedures, unlike C's
> printf(), are "magical".


Yes, they are. In the same way as variadic functions are magical.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
 
Reply With Quote
 
Jack Klein
Guest
Posts: n/a
 
      01-10-2006
On Mon, 09 Jan 2006 08:40:24 -0500, "Chuck F. " <(E-Mail Removed)>
wrote in comp.lang.c:

> Grumble wrote:
> >
> > As far as I understand, C89 and C99 leave the details of
> > parameter passing up to the implementation. For that reason,
> > I've claimed in comp.lang.asm.x86 that there is no such thing as
> > "the C calling convention". Am I mistaken? ]

>
> No. However, C is almost unique among languages in having the
> error prone variadic functions available, which in turn mandate
> having the first parameter in a known place, and makes the reverse
> order (assuming a stack, which is not necessary) attractive.


Some of the best compilers I have used pass parameters differently to
variadic and non-variadic functions. That means they break if one
calls a variadic function without a prototype in scope, but permission
to "break" on undefined behavior is inherent in the C standard, and
always has been.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
 
Reply With Quote
 
Chuck F.
Guest
Posts: n/a
 
      01-10-2006
Keith Thompson wrote:
> (E-Mail Removed) (Dag-Erling Smørgrav) writes:
>> "osmium" <(E-Mail Removed)> writes:

>
>>> When a knowledgeable person says "C calling convention",
>>> *this* is what he means. There is nothing analogous to
>>> printf() with it's indeterminate number of parameters in,
>>> Pascal, for example.

>>
>> Yes, there is. Write() and WriteLn() both take a variable
>> number of arguments. There is however no way for the
>> programmer to define a procedure which takes a variable number
>> of arguments.

>
> Yes, but as I recall the Write and WriteLn procedures, unlike
> C's printf(), are "magical". There's no format string, so it's
> up to the compiler to generate code based on the actual argument
> types. A compiler might typically generate a distinct procedure
> call for each argument. It's more like special-case overloading
> than C's "..." mechanism. Since the compiler can do whatever it
> likes, there's no need for special-purpose calling conventions
> to make everything come out right.


Depends on your point of view. I consider the C system to be
involving run time magic (for variadics), while the Pascal system
justs pumps out simple checked function calls. It isn't compiler
magic, it is just shorthand for a specific sequence.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C/C++ compilers have one stack for local variables and return addresses and then another stack for array allocations on the stack. Casey Hawthorne C Programming 3 11-01-2009 08:23 PM
x64 vs x86.. surprising results in performance (x86 better)? markm75 Windows 64bit 7 01-09-2008 06:41 PM
Why is there an x86 emu if a processor is x86-64? =?Utf-8?B?RWxsaW90IEh1ZGdpbnM=?= Windows 64bit 4 07-23-2006 11:52 PM
x86 Mac Laptop and x86 iMac now available Daniel NZ Computing 11 01-17-2006 12:11 PM
Is there a way with Linux x86 to report a way the current stack trace for a thread? kevin.hall@motioneng.com C++ 4 10-20-2005 09:43 PM



Advertisments