Is the output of following statement compiler dependent??
int i=100, j=20;
printf("%d, %d", printf("%d", i), printf("%d", j));
thanks in advance...
Chandrama Mishra
cmi...@feelings.com
-------------------==== Posted via Deja News ====-----------------------
http://www.dejanews.com/ Search, Read, Post to Usenet
cmi...@feelings.com wrote:
> Hello All,
>
> Is the output of following statement compiler dependent??
>
> int i=100, j=20;
> printf("%d, %d", printf("%d", i), printf("%d", j));
yes. The arguments to the outer printf can be evaluated in any order.
Either printf("%d", i) or printf("%d", j) can be evaluated first.
Note that the order is unspecified; it need not be documented and need
not be the same every time the statement is executed.
Michael M Rubenstein
Not if you remember to include <stdio.h> ;-) Ahhh, wait a minute,
except if this is the *last* "printf()" in "main()". If the last
"printf()" in "main()" is not terminated with an '\n' then the
result is implementation specific.
As far as C is concerned, stdout is used for outputting the text.
How stdout is implemented by the operating system or compiler may also
be different from system to system.
Stephan
(initiator of the campaign against grumpiness in c.l.c)
|> Hello All,
|>
|> Is the output of following statement compiler dependent??
|>
|> int i=100, j=20;
|> printf("%d, %d", printf("%d", i), printf("%d", j));
Yes. The C language does not specify the order in which function
arguments are evaluated, and an implementation may choose to evaluate
them in any arbitrarily bizarre order that it wishes.
Regards,
--
Chris Engebretson --- Hughes STX Corporation | Ph#: (605)594-6829
USGS EROS Data Center, Sioux Falls, SD 57198 | Fax: (605)594-6490
http://edcwww.cr.usgs.gov/ mailto:enge...@sg1.cr.usgs.gov
Opinions here are not those of Hughes Aircraft, STX, or the USGS.
lu...@powernet.net postm...@ybecker.net & tic...@cyberpromo.com
But we don't know if the printf with the i or the j would get called
first. That would depend on the compiler. A betting man may go with
the printf with the i being called first, but it's not a sure thing.
>Ahhh, wait a minute,
>except if this is the *last* "printf()" in "main()". If the last
>"printf()" in "main()" is not terminated with an '\n' then the
>result is implementation specific.
That is an interesting point -- just goes to show how different people
focus on different parts of a problem. :-)
--
Craig
clfr...@worldnet.att.net
Manchester, NH
I think the military is having a real problem at the
moment -- it has to train its recruits to kill, but
not to offend. -- Arianna Huffington
Craig Franck <clfr...@worldnet.att.net> wrote in article
<5vmbr9$n...@bgtnsc03.worldnet.att.net>...
> Stephan Wilms <Stepha...@CWA.de> wrote:
> >
> >cmi...@feelings.com wrote:
> >>
> >> Hello All,
> >>
> >> Is the output of following statement compiler dependent??
> >>
> >> int i=100, j=20;
> >> printf("%d, %d", printf("%d", i), printf("%d", j));
> >
> >Hi cmi...@feelings.com,
> >
> >Not if you remember to include <stdio.h> ;-)
>
> But we don't know if the printf with the i or the j would get
called
> first. That would depend on the compiler. A betting man may go
with
> the printf with the i being called first, but it's not a sure
thing.
Gee, I'd bet that on most architectures with stack based
parameter passing, the printf with the j would be called first,
because that return value must be pushed on the stack FIRST to
support the C calling convention. Of course speculating on
implementation specific behavior is the sort of thing we usually
complain about when other people do it...
While most compilers probably do it this way, the argument that they
must does not really follow, because even with stack-based parameter
passing, the parameters don't necessarily need to be pushed in
order if there is another way of getting them onto the stack.
For example, the most aggressive optimising compiler I have seen
for Intel Pentiums used stack-based parameter passing (for ABI
compliance), but set up the parameters by adjusting the stack
pointer all in one go, and then moving parameters into the stack
area it had allocated. It tended to evaluate parameter lists in
the opposite order to what is often considered the `natural' one,
though other optimisations could affect the order as well.
All perfectly legal, of course, according to the C Standard, which
says that the order of evaluation is `unspecified'.
|... Of course speculating on
|implementation specific behavior is the sort of thing we usually
|complain about when other people do it...
Exactly. :-)
You are right, this is something I overlooked. Together with that
other point I found, I will have to change my assesment of the
code to a definite "Yes, it is compiler dependant code".
> Gee, I'd bet that on most architectures with stack based
> parameter passing, the printf with the j would be called first,
> because that return value must be pushed on the stack FIRST to
> support the C calling convention.
First in stack, yes. First in time, definitely not. (There's no argument
about where the arguments need to go on the stack, but from that you
cannot infer the order (in time) that they get there...)
> Of course speculating on
> implementation specific behavior is the sort of thing we usually
> complain about when other people do it...
Indeed.
--Jim
>Craig Franck <clfr...@worldnet.att.net> wrote in article
><5vmbr9$n...@bgtnsc03.worldnet.att.net>...
>> >
>> >cmi...@feelings.com wrote:
>> >>
>> >> Is the output of following statement compiler dependent??
>> >>
>> >> int i=100, j=20;
>> >> printf("%d, %d", printf("%d", i), printf("%d", j));
>> >
>> But we don't know if the printf with the i or the j would get
>called
>> first. That would depend on the compiler. A betting man may go
>with
>> the printf with the i being called first, but it's not a sure
>thing.
>
>Gee, I'd bet that on most architectures with stack based
>parameter passing, the printf with the j would be called first,
>because that return value must be pushed on the stack FIRST to
>support the C calling convention. Of course speculating on
>implementation specific behavior is the sort of thing we usually
>complain about when other people do it...
The argument makes sense (this is what I expected, too), but... most
compilers I've tried call the printf with the i first. The only
exception I've found is gcc 2.7.0 on Linux. gcc 2.7.2.2 on various
RISC platforms behaves like the commercial compilers.
Anyway, the output DOES differ from platform to platform.
Dan
--
Dan Pop
CERN, IT Division
Email: Dan...@cern.ch
Mail: CERN - PPE, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
In interesting assertion, not supported by fact.
> Of course speculating on
> implementation specific behavior is the sort of thing we usually
> complain about when other people do it...
Indeed.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
In article <342014...@tiac.net>, Jim Sokoloff <soko...@tiac.net> wrote:
>Jack Klein wrote:
>
>> Gee, I'd bet that on most architectures with stack based
>> parameter passing, the printf with the j would be called first,
>> because that return value must be pushed on the stack FIRST to
>> support the C calling convention.
>
>First in stack, yes. First in time, definitely not. (There's no argument
>about where the arguments need to go on the stack, but from that you
>cannot infer the order (in time) that they get there...)
Bogon emission alarm!
There is no stack defined by the C languge. The precise mechanism for how
paramters acquire argument values is not specified. On RISC systems, it's
common to use registers for passing parameters.
--
Dan Pop wrote:
> The argument makes sense (this is what I expected, too), but... most
> compilers I've tried call the printf with the i first. The only
> exception I've found is gcc 2.7.0 on Linux. gcc 2.7.2.2 on various
> RISC platforms behaves like the commercial compilers.
>
Yep, implementation specific.
Older CISC compilers (VAX, PDP-11...) always evaluated the
expressions in a function call from right to left as the
previous poster supposed.
Note that on RISC platforms, chances are that the args are
passed in registers anyway.
With the hyper optimzing compilers these days, I wouldn't
even want to venture a guess as to how they would order
operations...
Kaz wrote:
>
> In article <342014...@tiac.net>, Jim Sokoloff <soko...@tiac.net> wrote:
> >Jack Klein wrote:
> >
> >> Gee, I'd bet that on most architectures with stack based
> >> parameter passing, the printf with the j would be called first,
> >> because that return value must be pushed on the stack FIRST to
> >> support the C calling convention.
> >
> >First in stack, yes. First in time, definitely not. (There's no argument
> >about where the arguments need to go on the stack, but from that you
> >cannot infer the order (in time) that they get there...)
>
> Bogon emission alarm!
Read the previous posts before emitting particles... Either that, or you
should have used a colon, instead of bang at the end... :-)
> There is no stack defined by the C languge. The precise mechanism for how
> paramters acquire argument values is not specified. On RISC systems, it's
> common to use registers for passing parameters.
Correct of course, but irrelevant since this particular fork of the
thread is discussing "architectures with stack based parameter passing"
And regardless of how the arguments are passed, there's still no
requirement for the time-order that those parameters get filled in.
--Jim
>>That would depend on the compiler. A betting man may go
>>with
>> the printf with the i being called first, but it's not a sure
>>thing.
>Gee, I'd bet that on most architectures with stack based
>Of course speculating on
>implementation specific behavior is the sort of thing we usually
>complain about when other people do it...
Yes -- but I said a betting man. :-) A true betting man will bet
on anything. Of coarse, the reason why it is a terrible coding
practice is it is possible to rewrite the code so as to eliminate
all doubt as to what will happen. This is the sort of program you
normally want to strive for.
Craig Franck wrote:
> Yes -- but I said a betting man. :-) A true betting man will bet
> on anything. Of coarse, the reason why it is a terrible coding
> practice is it is possible to rewrite the code so as to eliminate
> all doubt as to what will happen. This is the sort of program you
> normally want to strive for.
Is there EVER a case in a single-threaded C app when it's not possible
to rewrite the code in such a fashion?
---Jim
Jim Sokoloff <soko...@tiac.net> wrote in article
<342075...@tiac.net>...
Hi Jim,
This is an even better topic than the one Craig and I
inadvertently spawned. My gut instinct is to say no, especially
if we take "single-threaded C app" to mean "single-threaded
standard C app" (can multi-threaded C applications be 100%
standard?), but that's not my "official" answer. I want to
think about this one for a while...
Jack
Whenever I have the time, if my function has five bytes of parameters or
less, I do an exhaustive search of the input space to verify function
correctness. If there are eight or more bytes of inputs, tests must be
statistical to have any hope of thorough coverage. [I don't know of any
machine that can test 2^(8*CHAR_BIT) inputs in time resembling
reasonableness -- well. maybe a connection machine.]
This topic is probably better suited to a general programming group like
comp.programming.
I'm at home, so I say anything I please.
What I usually get out of a mathematical proof is assurance that only my
really dumb bugs are left, and they're usually easy to find.
David Thornley
>Note that on RISC platforms, chances are that the args are
>passed in registers anyway.
Even for variadic functions, a la printf (the case discussed here)?
In C:
Certainly. The caller typically doesn't know it's calling
a varargs function (prototypes are not strinctly required
for any function). The magic is in the called functions
processing of the arguments. This is what makes VARARGS
fun on these processor, you need to know which register
since int args are typically passed in int registers
and float args are passed in float registers. Take a peak
at stdard.h or varargs.h on such a machine.
>In C:
>Certainly. The caller typically doesn't know it's calling
>a varargs function (prototypes are not strinctly required
>for any function).
Calling a variadic function without a prototype in scope invokes
undefined behaviour in C. That's why the "hello world" program from
K&R2 includes <stdio.h>, while the one in K&R1 didn't.
|> Dan Pop wrote:
|> >
|> > In <34200D...@sensor.com> Ron Natalie <r...@sensor.com> writes:
|> >
|> > >Note that on RISC platforms, chances are that the args are
|> > >passed in registers anyway.
|> >
|> > Even for variadic functions, a la printf (the case discussed here)?
|>
|> In C:
|> Certainly. The caller typically doesn't know it's calling
|> a varargs function (prototypes are not strinctly required
|> for any function).
Nope.
The caller is *required* to "know" that it is calling a variadic
function. A call to, for example, printf() without a prototype in
scope for it is an error, and invokes undefined behavior. The
reason that a prototype is required for variadic functions is that
the language gives an implementation license to handle calls to
such functions differently than it would handle calls to "normal"
functions without variable argument lists.
As an example, (and this is part of what Dan was talking about), an
implementation could always use registers to pass arguments *except*
in the case of variadic functions, in which case it used the classic
"push-right-to-left-on-the-stack" method. This approach is fine and
conforms fully to the requirements that the language imposes on
translators. (I'm speaking only of what the language allows, and am
not trying to describe any one particular implementation.)
Beyond that, the statement "prototypes are not strictly required
for any function" is not correct. Keep in mind that arguments to
functions outside of the scope of a prototype are subject to the
language's default promotions (thus making it impossible to pass a
char as a char, a float as a float, etc.)
#include <stdio.h>
int main (void)
{
float bar = 3.141596;
foo(bar);
return 0;
}
int foo (float bar)
{
printf("%f\n", bar);
return 0;
}
An attempt to compile this innocent-looking code results in
cfe: Error: test.c, line 10: prototype and non-prototype
declaration found for foo, the type of this parameter
is not compatible with the type after applying default
argument promotion
int foo (float bar)
---------------^
However, making sure that a previous prototype is in scope for
foo() by adding a "int foo (float);" corrects this problem.
|> The magic is in the called functions
|> processing of the arguments. This is what makes VARARGS
|> fun on these processor, you need to know which register
|> since int args are typically passed in int registers
|> and float args are passed in float registers. Take a peak
|> at stdard.h or varargs.h on such a machine.
The point, again, is that while the language does not specify how
arguments are passed to functions, it also does not require an
implementation to use the same method all the time. The mechanism
used for variadic and non-variadic functions can be completely
different, so the fact that one particular RISC-based translator
uses registers for both genders of functions should not be viewed
as proof that they all will.
Regards,
--
Chris Engebretson --- Hughes STX Corporation | Ph#: (605)594-6829
USGS EROS Data Center, Sioux Falls, SD 57198 | Fax: (605)594-6490
http://edcwww.cr.usgs.gov/ mailto:enge...@sg1.cr.usgs.gov
Opinions here are not those of Hughes Aircraft, STX, or the USGS.
lu...@powernet.net postm...@4netbiz.com & tic...@cyberpromo.com
Bzzzt! That is false. Prototypes are absolutely required for a variadic
function! Variadic functions were introduced by ANSI, so they took the
liberty to add that restriction. If you call a variadic function without
a prototype, undefined behavior results.
>processing of the arguments. This is what makes VARARGS
>fun on these processor, you need to know which register
>since int args are typically passed in int registers
>and float args are passed in float registers. Take a peak
>at stdard.h or varargs.h on such a machine.
Take a peek at the standard while you are at it too!
--
Only on RISC machines with a variable number of registers. :-)
--
The Amorphous Mass "No manual entry for management."
amo...@avalon.net
http://www.avalon.net/~amorph
Kill spam dead: http://www.cauce.org
I think I would call displaying something on the output device a "side
effect!"
Norm
>Dan Pop (Dan...@cern.ch) wrote:
>>In <34200D...@sensor.com> Ron Natalie <r...@sensor.com> writes:
>>
>>>Note that on RISC platforms, chances are that the args are
>>>passed in registers anyway.
>>
>>Even for variadic functions, a la printf (the case discussed here)?
>
> Only on RISC machines with a variable number of registers. :-)
That must be one of those RISQUE machines.
--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------
>> Is the output of following statement compiler dependent??
>>
>> int i=100, j=20;
>> printf("%d, %d", printf("%d", i), printf("%d", j));
>
>yes. The arguments to the outer printf can be evaluated in any order.
So what? How does that effect the output? The two inner printf()
calls don't affect each other.
In some cases the expressions may have side effects, but not in this
particular case.
----- Dig the EVEN NEWER, MORE IMPROVED news sig!! -----
-------------- Shaggy was here! ---------------
http://aardvark.apana.org.au/~phaywood/
============= Ain't I'm a dawg!! ==============
> Groovy hepcat Mike Rubenstein was jivin' on Tue, 16 Sep 1997 11:22:46
> GMT in comp.lang.c.
> Re: Is it compiler dependent??'s a cool scene! Dig it!
>
> >> Is the output of following statement compiler dependent??
> >>
> >> int i=100, j=20;
> >> printf("%d, %d", printf("%d", i), printf("%d", j));
> >
> >yes. The arguments to the outer printf can be evaluated in any order.
>
> So what? How does that effect the output? The two inner printf()
> calls don't affect each other.
> In some cases the expressions may have side effects, but not in this
> particular case.
The two inner printf() calls don't affect each other but they do
affect the output. The order in which 100 and 20 are printed will
depend on the order in which the two inner printf()s are evaluated and
that is unspecified.
Michael M Rubenstein
Which gets printed first, the i or the j? The side effect is the
output could be 201003, 2 or 100203, 2 -- you can't tell from
looking at the code.
--
Craig
clfr...@worldnet.att.net
Manchester, NH
Maybe a great magnet pulls/All souls towards truth
Or maybe it is life itself/That feeds wisdom/To its
youth. -- k.d. lang
> phay...@aardvark.apana.org.au.STOP.SPAM (Peter "Shaggy" Haywood)
> wrote:
> >Groovy hepcat Mike Rubenstein was jivin' on Tue, 16 Sep 1997 11:22:46
>
> >GMT in comp.lang.c.
> >Re: Is it compiler dependent??'s a cool scene! Dig it!
> >
> >>> Is the output of following statement compiler dependent??
> >>>
> >>> int i=100, j=20;
> >>> printf("%d, %d", printf("%d", i), printf("%d", j));
> >>
> >>yes. The arguments to the outer printf can be evaluated in any
> order.
> >
> > So what? How does that effect the output? The two inner printf()
> >calls don't affect each other.
> > In some cases the expressions may have side effects, but not in
> this
> >particular case.
>
> Which gets printed first, the i or the j? The side effect is the
> output could be 201003, 2 or 100203, 2 -- you can't tell from
> looking at the code.
>
> --
Standard C calling convention statements are evaluated from right to
left. Pascal executes statements left to right I believe. You can turn
pascal calling conventions on and off using switches or put the the
keyword PASCAL in front of your function decleration to force it to use
a pascal calling convention.
Quinticent out!!!
--
-------------------------------------------------------
John Palmieri
Aka. Quinticent
E-Mail: Jo...@Mstarmedia.com
Quint...@aol.com
Quint...@earthling.net
Programmer - C/C++, Pascal, Delphi, Java1.1, JavaScript, Perl,
HTML, Director, Lingo, Shockwave,
Linux, MacOS, Win95/NT
--------------------------------------------------------
> Nonsense.
>
> There is no requirement in the standard for any particular order for
> evaluation of function arguments. Nor is there any requirement that
> an implementation document the order it uses.
>
> Nore is there any keyword PASCAL in the C language. In fact, a
> compiler that introduces such a keyword does not comply with the
> standard.
>
> The only switches defined by the C standard are statements and I
> cannot find anything in the standard telling me how to use them to
> turn "pascal calling conventions" on and off.
>
> Perhaps you are confused into thinking that just because the
> implementation you use does something, all must.
>
> Michael M Rubenstein
I'm sorry, after researching it more in debth I found out PASCAL is
defined in the windows library and is now obsolete. But my Turbo C++
compiler has an option for turing off and on pascal calling
conventions. However evaluation should be standard if it is not
already. Sorry if I misled anybody.
On your platform, with your compiler, it may be (probably is, since it's
that way on mine too) true but IT IS NOT a standard C or C++
requirement. The C standard and the draft C++ standard DO NOT SPECIFY
the order of evaluation of function arguments.
That is the whole point of this thread from the beginning.
Norm
Followup to comp.unix.programmer deleted; they probably don't care to
see this!
PASCAL is actually a macro which expands to __pascal. This is a language
extension available in Borland and other PC compilers to generate code
with Pascal calling sequences.
The Pascal calling sequence does evaluate the arguments from left to
right. It also expects the called routine to clean up the stack; this
can be slightly more efficient with the Intel CPU. It means, however,
that the function CANNOT BE VARIADIC so the __pascal could never be used
with printf().
__pascal IS NOT OBSOLETE. It is still the calling sequence to be used
for most of the Windows API. The Microsoft developers must have felt
that the slight increase in efficiency was worth the slight
inconvenience of requiring the __pascal keyword.
Norm
Nonsense.
Huh ?? The expressions here are being used for nothing _other_ than
their side effects ... As to whether the code invokes undefined
behavior, note that if the compiler chooses to evaluate the arguments
to the outer 'printf()' from left to right, the output is "100203, 2"
while you'll get "201003, 2" if it chooses the other order.
|>
|> ----- Dig the EVEN NEWER, MORE IMPROVED news sig!! -----
|>
|> -------------- Shaggy was here! ---------------
|> http://aardvark.apana.org.au/~phaywood/
|> ============= Ain't I'm a dawg!! ==============
|>
--
Ed Hook | Copula eam, se non posit
Computer Sciences Corporation | acceptera jocularum.
NASA Langley Research Center | Me? Speak for my employer?...<*snort*>
Internet: ho...@cscsun3.larc.nasa.gov | ... Get a _clue_ !!! ...
> Mike Rubenstein wrote:
>
> > Nonsense.
> >
> > There is no requirement in the standard for any particular order for
> > evaluation of function arguments. Nor is there any requirement that
> > an implementation document the order it uses.
> >
> > Nore is there any keyword PASCAL in the C language. In fact, a
> > compiler that introduces such a keyword does not comply with the
> > standard.
> >
> > The only switches defined by the C standard are statements and I
> > cannot find anything in the standard telling me how to use them to
> > turn "pascal calling conventions" on and off.
> >
> > Perhaps you are confused into thinking that just because the
> > implementation you use does something, all must.
> >
> > Michael M Rubenstein
>
> I'm sorry, after researching it more in debth I found out PASCAL is
> defined in the windows library and is now obsolete. But my Turbo C++
> compiler has an option for turing off and on pascal calling
> conventions. However evaluation should be standard if it is not
> already. Sorry if I misled anybody.
You need to research it in still more depth. The question was whether
the result was implementation-dependent. What your particular
compiler does has nothing to to with that.
You are still missing the point -- there is no such thing as "pascal
calling conventions" in standard C. There are implementations (most
non-PC implementations) in which there is no such concept.
And the question was not whether the order of evaluation should be
standard; it was whether it is. It is not.
But there's also the question of why it should be standard.
Ok. Let's standardize; we'll require evaluation of arguments be from
left to right. So what if it means that Borland will have to update
their compilers and make them less efficient. Surely no one will
object once they learn that John Palmieri thinks that the order should
be standard.
Or maybe we should require the order be from right to left. I'm sure
that the makers of compilers where this is less efficient will
understand that since John Palmieri doesn't own their compilers this
is unimportant.
Michael M Rubenstein
Mike is absolutely correct about this.
[big snip]
Norman Bullen wrote:
> The Pascal calling sequence does evaluate the arguments from left to
> right. It also expects the called routine to clean up the stack; this
> can be slightly more efficient with the Intel CPU. It means, however,
> that the function CANNOT BE VARIADIC so the __pascal could never be used
> with printf().
Mr. Bullen and other contributors to this thread are
confusing { argument order as seen by callees } with
{ argument evaluation order as performed by callers }.
There is nothing to relate those two in a reliable way.
In the presence of optimization, it may easily happen
that an argument is evaluated "out of order" with respect
to the order arguments might be "pushed". (I put the
term in quotes because on some architectures, such as
SPARC, most arguments are never pushed onto a stack.)
So, to summarize, "Pascal calling sequence" is a misnomer
as applied to individual arguments. It only specifies
argument ordering as seen by callees and stack (or
whatever) cleanup responsibility. Evaluation order is
totally unspecified, just as Mike has been stating.
> __pascal IS NOT OBSOLETE. It is still the calling sequence to be used
> for most of the Windows API. The Microsoft developers must have felt
> that the slight increase in efficiency was worth the slight
> inconvenience of requiring the __pascal keyword.
The efficiency gain is 1 instruction per call. For
call-intensive code, this is more than "slight" IMHO.
Since the keyword need only appear once in function
prototypes that should be #include'd anyway, the
inconvenience is vanishingly small.
--
--Larry
work: (425)557-1670 lar...@SsPqAiM.com
home: (206)236-2121 lar...@eaSrtPhlAinMk.net
Aforementioned views are likely mine alone.
(Remove "SPAM" from address for an email reply.)
> So what? How does that effect the output? The two inner printf()
> calls don't affect each other.
> In some cases the expressions may have side effects, but not in this
> particular case.
Umm, printf doesn't have side effects? I always thought that it's
primary purpose was the side effect of generating output to stdout.
---Jim
>> __pascal IS NOT OBSOLETE. It is still the calling sequence to be used
>> for most of the Windows API. The Microsoft developers must have felt
>> that the slight increase in efficiency was worth the slight
>> inconvenience of requiring the __pascal keyword.
>
>The efficiency gain is 1 instruction per call. For
>call-intensive code, this is more than "slight" IMHO.
>Since the keyword need only appear once in function
>prototypes that should be #include'd anyway, the
>inconvenience is vanishingly small.
The "Microsoft developers" could have had the best of both worlds for
ANSI C. Since it is illegal in C to call a variadic function without
a prototype in scope the natural approach would be for the compiler
to use internally the "Pascal" calling convention unless a variadic
funcion is being called or defined in which case the normal "C" calling
convention is used. There's no need for a __pascal keyword.
Maybe they didn't want to have to explain to their customers why simply
making *this* module ANSI-compliant causes code in *that* (non-compliant)
module to break. In olden times (circa K&R1), the following was pretty
much guaranteed to work (because "arguments are pushed onto the stack
in reverse order"):
prtlst(dummy)
{
char **argp = (char **)&dummy; /* Is this ugly or what? */
do printf("%s\n",*argp++);
while (*argp);
}
main()
{
prtlst("Who's on first","What's on second","I Don't Know's on third",0);
}
--
Dave Lewis, ma...@panix.com, NYC
As a matter of fact, the recent versions of Microsoft's
C/C++ compiler do exactly this, except under the control
of a code-generation option. Doing this as a default or
not optionally is not quite quite feasable because of the
(presumable) need to call into existing .obj modules and
DLL's. I believe that the MS C++ compiler does use the
Pascal calling convention for C++ non-static non-varadic
member methods. If it were not for the C legacy, your
position would be perfectly sensible. (That C legacy has
to include pre-ANSI C, which did not require prototypes
in the way you mention. That is an ANSI C contribution,
and one which shows (to me, at least) that sometimes a
committee can do better than a few individuals.)
...
>Maybe they didn't want to have to explain to their customers why simply
>making *this* module ANSI-compliant causes code in *that* (non-compliant)
>module to break. In olden times (circa K&R1), the following was pretty
>much guaranteed to work (because "arguments are pushed onto the stack
>in reverse order"):
>
> prtlst(dummy)
> {
> char **argp = (char **)&dummy; /* Is this ugly or what? */
>
> do printf("%s\n",*argp++);
> while (*argp);
> }
>
> main()
> {
> prtlst("Who's on first","What's on second","I Don't Know's on third",0);
> }
If the code depends on non-ANSI behaviour simply compile it using the
appropriate non-ANSI comilation options. There will always be issues
linking to code compiled with different options or a different compiler
but there's no reason why new code needs to be shackled with the same
limitations.
Posting in an frustrated or angry frame of mind sure results in very
grumpy replies. Or are you trying to increase your flames per day
ration ?
Stephan
(initiator of the campaign against grumpiness in c.l.c)
Janus <j...@iol.ie> wrote in article <346a7c63...@news.iol.ie>...
| Gaia dhuit,
|
| Mike Rubenstein dropped 2 cents in the slot of <comp.lang.c>
| in article <34293b52....@nntp.ix.netcom.com>,
| and he wrote to us :
|
| >You need to research it in still more depth. The question was whether
| >the result was implementation-dependent. What your particular
| >compiler does has nothing to to with that.
| >
| Gosh the original poster is in serious trouble now !
| His compiler has nothing to do with his implementation !
|
| New compiler required ?
|
| >Ok. Let's standardize;
|
| Let's.
|
| >we'll require evaluation of arguments be from
| >left to right. So what if it means that Borland will have to update
| >their compilers and make them less efficient.
| >
| Or... it might make some Microsoft code overly bloated, and prone to
| random crashes for no apparent reason.
off topic. Go to one of the alt.flame newsgroups and spare us your
worthless sarcasm.
|
| (HEY, Standard readers :
| are we *sure* this isn't the standard evaluation ?)
| >
| >Or maybe we should require the order be from right to left. I'm sure
| >that the makers of compilers where this is less efficient will
| >understand that since John Palmieri doesn't own their compilers this
| >is unimportant.
| >
| But it is important to them what John thinks.
| He's still in the market looking for a new compiler.
|
| --
| janus j...@iol.ie"
| http://www.iol.ie/~jab/c/coal.html
|
| digger of the campaign for begrudgery in c
|
| Gaia leat
|
>
> >>Umm, printf doesn't have side effects? I always thought that it's
> >>primary purpose was the side effect of generating output to stdout.
> >>
> >
> >I agree with what you say, but i don't like the way we must say it.
> >
> >Is there something wrong with a jargon that insists that
> >"Its side effects are the primary purpose of X" ?
>
>
> Now hold on, a function has an effect and eventually sometimes a side
> effect. The effect of a function is not always it's return value.
> (How about void functions.) The effect of printf to put things on
> stdout vs the fact that you get the number of bytes put out. Which of
> the two shall we call the effect, and which of them the side effect?
>
>
> I like this kind of philosophy, esp. on sunday morning, but it doesn't
> bring us nearer to the essentials of C does it?
Fortunately, the standard provides an answer. 5.1.2.3 defines a side
effect:
Accessing a volatile object, modifying an object, modifying a
file, or calling a function that does any of those operations
are all side effects, which are changes in the state of the
execution environment.
Michael M Rubenstein
>>Umm, printf doesn't have side effects? I always thought that it's
>>primary purpose was the side effect of generating output to stdout.
>>
>
>I agree with what you say, but i don't like the way we must say it.
>
>Is there something wrong with a jargon that insists that
>"Its side effects are the primary purpose of X" ?
Now hold on, a function has an effect and eventually sometimes a side
effect. The effect of a function is not always it's return value.
(How about void functions.) The effect of printf to put things on
stdout vs the fact that you get the number of bytes put out. Which of
the two shall we call the effect, and which of them the side effect?
I like this kind of philosophy, esp. on sunday morning, but it doesn't
bring us nearer to the essentials of C does it?
|> Mike Rubenstein wrote:
|>
|> > > > Nor is there any keyword PASCAL in the C language. In fact, a
|> > > > compiler that introduces such a keyword does not comply with the
|> > > > standard.
|>
|> Why, where in the standard does it specifically exclude the introduction
|> of a keyword to specify a calling convention to allow compatibility with
|> another language. I know that the standard has nothing to say about
|> mixed-language programming, but I was unaware that the standard
|> specifically excluded this sort of thing.
|>
|> Please direct me to the relavant parts of the standard.
[ pedantry alert ]
The subclause that you're looking for is 5.1.1.3; please take the
time to read over what it has to say at your earliest convenience.
I would quote some of the relevant text, but that would probably
be pointless as I expect you'll look it up in your own copy.
The reason why such an implementation is not conforming is that the
introduction of a keyword as described above *violates the syntax
of the language.* Now, while an implementor is free to add whatever
extensions to the syntax he or she wants, the compiler is *not a
conforming implementation* when such extensions are active! This
is generally not a terribly important issue, as implementations that
provide such extensions also provide an escape hatch (be it a switch
on the command line, etc.) that "reverts" to a conforming mode.
A working example here is gcc; I have no problems with it as a
compiler, and it is not a conforming implementation by default in
that it allows "nested functions", which violates the syntax of the
C language. However, through the use of command line switches (in
this case, "-ansi -pedantic-errors"), gcc disallows the extension
and produces the diagnostic that the language requires it to. The
gist here is that the implementation is certainly not conformant
when the extension is active, but can (hopefully!) be *made to be*
conformant by telling the compiler "Hey, I don't want to use all
your special 'features' .. I want to write straight C code."
An effect of a function should *always* be perceivable by the program,
side-effects are not always perceivable by the program.
Here the effect of printf() is the return value specifying the number
bytes placed on stdout. this is perceivable by the program. The
programmer can test the return value and compare it to a specified value
to determine how successful printf() was. The side-effect of actually
placing the bytes in the stream, is not always perceivable to the
program. If stdout is connected to a memory mapped display or a dumb
terminal the program may not be able to perceive the effects of the
bytes placed on stdout. If stdout has be freopened() to go to a file,
the program, after, freopen()ing stdout back to the console or terminal
or whereever (or after fclose()ing stdout, if that is what you want to
do). The program can examine the file (by opening another stream and
examining the contents of that new stream) to determin what the
side-effects of printf() were.
Anyway, I place the above definition of effects vs side-effects out to
c.l.c for discussion, derision, or flames. Have fun, guys.
> I like this kind of philosophy, esp. on sunday morning, but it doesn't
> bring us nearer to the essentials of C does it?
--
************************************************
* Alicia Carla Longstreet ca...@ici.net *
* Remove the _JUNK_ when replying to me. *
************************************************
My programming is Wobbly. It's good programming but it Wobbles,
and the statements sometimes get in the wrong places.
************************************************
C appeals due to is simplicity and elegance.
> > Mike Rubenstein wrote:
> > > Nor is there any keyword PASCAL in the C language. In fact, a
> > > compiler that introduces such a keyword does not comply with the
> > > standard.
Why, where in the standard does it specifically exclude the introduction
of a keyword to specify a calling convention to allow compatibility with
another language. I know that the standard has nothing to say about
mixed-language programming, but I was unaware that the standard
specifically excluded this sort of thing.
Please direct me to the relavant parts of the standard.
> You need to research it in still more depth. The question was whether
> the result was implementation-dependent. What your particular
> compiler does has nothing to to with that.
I must have missed something. Apparently this paragraph has no meaning
when taken out of context. I had always thought that the compiler was
the implementation so it is confusing to see someone say that the
specific results of a compiler has nothing to do with an
implementation-dependent result. I would think that exactly the opposit
is true.
> You are still missing the point -- there is no such thing as "pascal
> calling conventions" in standard C. There are implementations (most
> non-PC implementations) in which there is no such concept.
Actually, from what I have read and seen on this forum, there is
apparently no specific calling conventions in the standard at all. Some
implementations allow the programmer to select between a method of
calling functions originally specified by the Pascal programming
language (I believe) vs a calling convention sometimes mistakenly
referred to as the C calling convention (being that it is a method often
used by C compilers). Some implementations do not allow the programmer
to specify how a functions is called, or if they do they have chosen to
call the different conventions by other names. Depending on the
underlying architecture some implementations my use the 'pascal calling
convention' by default or exclusively, other implementations may mix and
match, using the calling method that is optimal for the particular
function.
[snip]
It doesn't exclude mixed-language programming. But adding a new keyword
has the effect of causing the compiler not to accept some conforming
programs.
PASCAL is a legal C identifier.
If a compiler makes PASCAL a keyword, then a conforming program using
PASCAL as a keyword will not be accepted.
Given a compiler that uses keyword PASCAL to specify "pascal calling
conventions", as in
int PASCAL foobar(int a, float b);
the line:
int PASCAL = 9;
...would be rejected, even though it's perfectly legal C, since
if the compiler thinks of PASCAL as a keyword.
If there's a need to specify a certain calling convention, there are at
least two ways to do it without introducing a new keyword.
|> Please direct me to the relavant parts of the standard.
|> > You need to research it in still more depth. The question was whether
|> > the result was implementation-dependent. What your particular
|> > compiler does has nothing to to with that.
|> I must have missed something. Apparently this paragraph has no meaning
|> when taken out of context. I had always thought that the compiler was
|> the implementation so it is confusing to see someone say that the
|> specific results of a compiler has nothing to do with an
|> implementation-dependent result.
That's not what he said. Read it again.
"The question was whether the result was implementation-dependent.
What your particular compiler does has nothing to to with that."
The antecedent of "that" is "whether the result was
implementation-dependent".
The standard decides what's implementation-dependent; the
implementation decides the results. It's not that hard a concept.
> Mike Rubenstein wrote:
>
> > > Mike Rubenstein wrote:
>
> > > > Nor is there any keyword PASCAL in the C language. In fact, a
> > > > compiler that introduces such a keyword does not comply with the
> > > > standard.
>
> Why, where in the standard does it specifically exclude the introduction
> of a keyword to specify a calling convention to allow compatibility with
> another language. I know that the standard has nothing to say about
> mixed-language programming, but I was unaware that the standard
> specifically excluded this sort of thing.
>
> Please direct me to the relavant parts of the standard.
PASCAL is not a keyword. Keywords are listed in ISO 6.1.1 and PASCAL
is not one of them. PASCAL is an identifier. Reserved identifiers
are listed (partly by reference) in 7.1.3. PASCAL is not listed and
7.1.3 prohibits an implementation from introducing additional reserved
identifiers. PASCAL may be defined as an identifier in a nonstandard
header, but that would only be of concern if the nonstandard header
were included.
An implementation may use reserved identifiers to allow compatibility
with another language, or for any other purpose, but they must be
identifiers that are reserved by the standard. For example, _PASCAL
or __pascal could be used since they are reserved by 7.1.3.
A conforming compiler must accept the program
int main(void)
{
int PASCAL = 0;
return PASCAL;
}
It is not required to accept the program
int main(void)
{
int _PASCAL = 0;
return _PASCAL;
}
and if it does accept it, it can do anything the implementator feels
like.
The standard reserves many identifiers that are not defined by the
standard. This is to allow implementations to use such identifiers
for this kind of thing without interfering with strictly conforming
programs.
>
> > You need to research it in still more depth. The question was whether
> > the result was implementation-dependent. What your particular
> > compiler does has nothing to to with that.
>
> I must have missed something. Apparently this paragraph has no meaning
> when taken out of context. I had always thought that the compiler was
> the implementation so it is confusing to see someone say that the
> specific results of a compiler has nothing to do with an
> implementation-dependent result. I would think that exactly the opposit
> is true.
Specific results of a compiler have nothing to do with WHETHER the
result is implementation-dependent. The original question was whether
a the results of a particular expression that depend on order of
evaluation of arguments is implementation-dependent. What a
particular compiler does has nothing to do with this question.
>
> > You are still missing the point -- there is no such thing as "pascal
> > calling conventions" in standard C. There are implementations (most
> > non-PC implementations) in which there is no such concept.
>
> Actually, from what I have read and seen on this forum, there is
> apparently no specific calling conventions in the standard at all. Some
> implementations allow the programmer to select between a method of
> calling functions originally specified by the Pascal programming
> language (I believe) vs a calling convention sometimes mistakenly
> referred to as the C calling convention (being that it is a method often
> used by C compilers). Some implementations do not allow the programmer
> to specify how a functions is called, or if they do they have chosen to
> call the different conventions by other names. Depending on the
> underlying architecture some implementations my use the 'pascal calling
> convention' by default or exclusively, other implementations may mix and
> match, using the calling method that is optimal for the particular
> function.
But there is no such thing as "the pascal calling convention." There
are calling conventions on some compilers that are called pascal
calling convention, but lacking a standard one cannot talk about "the
pascal calling convention" except in regard to a specific compiler.
Michael M Rubenstein
In the section which describes what storage class specifiers, type
specifiers and type qualifiers are permitted in a declaration.
The word ``pascal'' is free to be used as an identifier. If you write
pascal int foo();
it is a syntax error that requires a diagnostic. Of course, the
implementation is free to nevertheless ``do its pascal thing'', but if the
diagnostic is not issued, it's not behaving in a conforming manner.
The implementation also must not prevent the user from using ``pascal''
as an identifier.
> I know that the standard has nothing to say about
>mixed-language programming, but I was unaware that the standard
>specifically excluded this sort of thing.
It excludes this sort of thing, but it does not preclude mixed-language
programming. Extensions are supported via the #pragma mechanism, and via any
undefined behavior. Also, an implementation may actually be a collection of
different implementations, some of which are conforming. You could provide an
entire mode of operation that causes function definitions and invocations to
be translated into the calling conventions of a particular programming
language.
>Please direct me to the relavant parts of the standard.
Section 6.5, Declarations.
--
> Mike Rubenstein wrote:
>
> > > Mike Rubenstein wrote:
>
> > > > Nor is there any keyword PASCAL in the C language. In fact, a
> > > > compiler that introduces such a keyword does not comply with the
> > > > standard.
>
> Why, where in the standard does it specifically exclude the introduction
> of a keyword to specify a calling convention to allow compatibility with
> another language. I know that the standard has nothing to say about
> mixed-language programming, but I was unaware that the standard
> specifically excluded this sort of thing.
>
> Please direct me to the relavant parts of the standard.
PASCAL is just a normal identifier. Therefore a compiler must compile
static int PASCAL;
as a declaration of a static variable of type int with the name "PASCAL".
void PASCAL my_pascal_function (void);
is not legal C. An ANSI C compiler is allowed to compile this after giving
a diagnostic. But now two methods that invoke "undefined behavior" (which
means the behavior is not defined by the ANSI C Standard, so anything can
happen, including the behavior that you want):
#include <pascal.h>
void pascal my_pascal_function (void);
or
void __pascal my_pascal_function (void);
This is obviously not legal C, but any ANSI C compiler is allowed to
compile it without a diagnostic. The first one invokes undefined behavior
by using an #include statement that looks like including a standard header
file, when <pascal.h> is not a standard header. The second one invokes
undefined behavior by using an identifier that starts with two "_"
characters.
...
>As a matter of fact, the recent versions of Microsoft's
>C/C++ compiler do exactly this, except under the control
>of a code-generation option. Doing this as a default or
>not optionally is not quite quite feasable because of the
>(presumable) need to call into existing .obj modules and
>DLL's.
The obvious question is whether Microsoft could have adopted this when
it designed win32.
> Now hold on, a function has an effect and eventually sometimes a side
> effect. The effect of a function is not always it's return value.
> (How about void functions.)
A side effect is anything material that happens during expression evaluation
apart from yielding a value.
Void expressions, including calls of void functions, have only
side effects, or no effects of any kind at all.
The same goes for every expression that forms the body of an
expression statement, since the value is always discarded.
Let's not forget that the actual "assignment" process is "only" :-)
a side-effect of evaluating an assignment-expression.
Side-effects are what it's all about.
--
Unfortunately this definition does not conform to what normally are
called "side effects". According to this definition the function:
void f(void) { int i = 1; i = 2; }
is a function with "side effects".
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
>> > > Nor is there any keyword PASCAL in the C language. In fact, a
>> > > compiler that introduces such a keyword does not comply with the
>> > > standard.
>
>Why, where in the standard does it specifically exclude the introduction
>of a keyword to specify a calling convention to allow compatibility with
>another language.
4 Compliance
[...]
A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any
strictly conforming program. [* 2]
[...]
[* 2] This implies that a conforming implementation reserves no
identifiers other than those explicitly reserved in this International
Standard.
[...]
Show me an implementation which reserves the keyword PASCAL and I show
you a strictly conforming program which will not compile on this
implementation.
Which leads us to the fact: an implementation which reserves the
keyword PASCAL ( replace PASCAL with any keyword or identifier not
defined in the standard) is no longer a conforming implementation.
>I know that the standard has nothing to say about
>mixed-language programming, but I was unaware that the standard
>specifically excluded this sort of thing.
Not specifically but implicitly.
Replace PASCAL with __pascal or _PASCAL and everything's just fine.
ByE, MarKus.
( To reply by e-mail remove the 'R' in my e-mail address )
Simon.
|> On Mon, 29 Sep 1997 14:47:07 -0400, Alicia Carla Longstreet
|> <ca...@ici.net> wrote:
|>
|> >Why, where in the standard does it specifically exclude the introduction
|> >of a keyword to specify a calling convention to allow compatibility with
|> >another language.
|>
|> Which leads us to the fact: an implementation which reserves the
|> keyword PASCAL ( replace PASCAL with any keyword or identifier not
|> defined in the standard) is no longer a conforming implementation.
Indeed it isn't.
|> Replace PASCAL with __pascal or _PASCAL and everything's just fine.
However, in the context in which it was discussed (and to relate to
ACL's question ".. where in the standard does it specifically exclude
the introduction of a keyword to specify a calling convention .."),
it still cannot be used by a conforming implementation. That is, the
following example
int __pascal myfunc (int a, float b, char c);
is a syntax error which must be diagnosed. Obviously a conforming
implementation may choose to provide this extension as an option,
but as long as the extension is "active", the implementation is not
conforming because it fails to produce the required diagnostic.
Of course, the issue of "PASCAL" not belonging to the implementation
namespace is a more immediate concern (and something that I neglected
to mention in my original followup to ACL's question.)
> > >> int i=100, j=20;
> > >> printf("%d, %d", printf("%d", i), printf("%d", j));
> Gee, I'd bet that on most architectures with stack based
> parameter passing, the printf with the j would be called first,
> because that return value must be pushed on the stack FIRST to
> support the C calling convention. Of course speculating on
> implementation specific behavior is the sort of thing we usually
> complain about when other people do it...
The C standard allows the function calls to happen in any order, and the
parameters pushed in the oposite order if you (C compiler writer) want to,
if only to be as incompatible as possible with your competition on the same
machine ;-)
--
Dr. Horst H. von Brand mailto:vonb...@inf.utfsm.cl
Departamento de Informatica Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria +56 32 654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513
Which would break on the once common Small C compiler.
Ulric
--
I proactively leverage my synergies.
...
>However, in the context in which it was discussed (and to relate to
>ACL's question ".. where in the standard does it specifically exclude
>the introduction of a keyword to specify a calling convention .."),
>it still cannot be used by a conforming implementation. That is, the
>following example
>
> int __pascal myfunc (int a, float b, char c);
>
>is a syntax error which must be diagnosed.
That cannot be proven. For example the implementation may define __pascal
as a macro that expands to something that does not cause a syntax
error in this context. All that can be said about this is that it
results in undefined behaviour therefore it is a valid extension for a
conforming implementation and no diagnostic is required.
|> In article <EHDrx...@igsrsparc2.er.usgs.gov>
|> enge...@sg1.cr.usgs.gov "Chris Engebretson" writes:
|>
|> ...
|>
|> >However, in the context in which it was discussed (and to relate to
|> >ACL's question ".. where in the standard does it specifically exclude
|> >the introduction of a keyword to specify a calling convention .."),
|> >it still cannot be used by a conforming implementation. That is, the
|> >following example
|> >
|> > int __pascal myfunc (int a, float b, char c);
|> >
|> >is a syntax error which must be diagnosed.
|>
|> That cannot be proven. For example the implementation may define __pascal
|> as a macro that expands to something that does not cause a syntax
|> error in this context. All that can be said about this is that it
|> results in undefined behaviour therefore it is a valid extension for a
|> conforming implementation and no diagnostic is required.
Quite so. I'd gotten to thinking about this a bit more, and came to
realize that even the point made by other posters to this thread that
"PASCAL is not in the implementation namespace, therefore a conforming
implementation is not allowed to use it as a keyword" is also false.
Certainly a conforming implementation cannot accept a program like
int PASCAL myfunc (int a, float b, char c);
int main (void) { return 0; }
and it must accept a program like
int main (void) { int PASCAL = 0; return PASCAL; }
but what prevents it from accepting the following?
#include <pascal.h>
int PASCAL myfunc (int a, float b, char c);
int main (void) { return 0; }
The point that "PASCAL" does not belong to the implementation is
still valid, of course, but it is not a particularly important point
to the third program. The third example invokes undefined behavior
on its very first line, and obviously a perfectly valid example of
undefined behavior could be the reservation of an identifier or two
that the implementation is not supposed to touch.
Another way of looking at it, I guess, is that all a conforming
implementation must do is translate strictly-conforming programs;
since there is no strictly-conforming program that can ever
#include <pascal.h>, Compiler XXX is free to introduce this keyword
when said header is included and still be a perfectly conforming
implementation.
...
>Quite so. I'd gotten to thinking about this a bit more, and came to
>realize that even the point made by other posters to this thread that
>"PASCAL is not in the implementation namespace, therefore a conforming
>implementation is not allowed to use it as a keyword" is also false.
>
>Certainly a conforming implementation cannot accept a program like
>
> int PASCAL myfunc (int a, float b, char c);
> int main (void) { return 0; }
>
>and it must accept a program like
>
> int main (void) { int PASCAL = 0; return PASCAL; }
>
>but what prevents it from accepting the following?
>
> #include <pascal.h>
>
> int PASCAL myfunc (int a, float b, char c);
> int main (void) { return 0; }
>
>The point that "PASCAL" does not belong to the implementation is
>still valid, of course, but it is not a particularly important point
>to the third program. The third example invokes undefined behavior
>on its very first line, and obviously a perfectly valid example of
>undefined behavior could be the reservation of an identifier or two
>that the implementation is not supposed to touch.
It could certainly do that but a defined identifier is not the same
thing as a keyword (which is a syntactic element that is "defined"
under all circumstances).
>Another way of looking at it, I guess, is that all a conforming
>implementation must do is translate strictly-conforming programs;
That is the definition of a conforming implementation (well, one of the
requirements anyway).
>since there is no strictly-conforming program that can ever
>#include <pascal.h>, Compiler XXX is free to introduce this keyword
>when said header is included and still be a perfectly conforming
>implementation.
Right. I think the original issue though was when a diagnostic was required.
In your PASCAL example a diagnostic isn't required because it can't be
proven to have a syntax error (or constraint violation).
[...]
>#include <pascal.h>, Compiler XXX is free to introduce this keyword
>when said header is included and still be a perfectly conforming
>implementation.
I don't agree, because the semantics of including a header do not
include a new definition of a keyword. The implementation can choose
where to look and how to identify the header but not what to do with
this header. The semantics are to cause "the replacement of that
directive by the entire contents of the header".
What you intent to point out could be pointed out just like this:
#pragma allow keyword pascal
/* etc... */
An implementation which implements new keywords like this would be
conforming.
It comes all down to one question: allows the implementation to switch
it on/off and is it by default switched off ( In case it can be
switched by a pragma directive )?
What if #include <fortran.h> sucked in #pragma FORTRAN-77 MODE?
>What you intent to point out could be pointed out just like this:
>
>#pragma allow keyword pascal
>/* etc... */
>
>An implementation which implements new keywords like this would be
>conforming.
Because the #pragma causes the implementation to behave in an
implementation-defined manner.
>It comes all down to one question: allows the implementation to switch
>it on/off and is it by default switched off ( In case it can be
>switched by a pragma directive )?
Once you include a non-standard header, anything can happen.
#include<duh.h>
DONT_CARE ManiAc(NO_ARGS)
{
SeeYaRealSoon EXIT_BYE_BYE;
}
It's no longer a strictly conforming C program because of #include<duh.h>,
but it conforms because we have no clue as to what happened when the non-
standard header was included (even standard headers don't need to contain
C-code).
--
Craig
clfr...@worldnet.att.net
Manchester, NH
Maybe a great magnet pulls/All souls towards truth
Or maybe it is life itself/That feeds wisdom/To its
youth. -- k.d. lang
Well, taking into account that
/* pascal.c */
#include <stdio.h>
void pascal(char *text);
int main(void)
{
pascal("This is Pascal");
return EXIT_SUCCESS;
}
void pascal(char *text)
{
printf("%s\n",text);
}
is strictly conforming program, but
/* pascal1.h */
void pascal(char *text);
/* pascal1.c */
#include <stdio.h>
#include <pascal1.h>
int main(void)
{
pascal("This is Pascal");
return EXIT_SUCCESS;
}
void pascal(char *text)
{
printf("%s\n",text);
}
is not -
is there any practical meaning in the term "strictly conforming
program" other than in context of an obligatory requirement to
a conforming implementation?
Regards,
Alex Krol
|> [ Is ] there any practical meaning in the term "strictly conforming
|> program" other than in context of an obligatory requirement to
|> a conforming implementation?
Yes. The practical meaning is that of a "maximally portable" program;
that is, one that is guaranteed to translate successfully and behave
in a uniform manner across all conforming implementations. Since the
standard describes eighteen headers of which <pascal1.h> is not, you
can't expect this header to be present across implementations.
Granted, non-trivial programs that are entirely strictly-conforming
are extremely rare; I don't write completely strictly-conforming code
for a living and know nobody that does. The importance of the language
described by the standard is that it allows you to determine what parts
of your code are portable and what parts are not, and to provide the
appropriate documentation and/or "portability crutches" (such as
typedefs or #ifdef/#endif pairs, if applicable.)