By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,928 Members | 1,773 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,928 IT Pros & Developers. It's quick & easy.

what is the output of this program?

P: n/a

This came up in a job interview, what is the output of the program
below? I tried to compile and run it myself, but my compiler (lcc-win32)
aborts with this errors....

Warning test2.c: 3 old-style function definition for 'main'
Warning test2.c: 3 missing prototype for 'main'
Warning test2.c: 3 '
Error test2.c: 3 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error c:\test\test2.c 3 Compiler error (trap). Stopping compilation
1 error

Here is the program....

1: #include <stdio.h>
2: void main()
3: {
4: int C = 0;
5: printf("C %s C++\n", C == C++ ? "==" : "!=");
6: }

I don't even have a d:\lcc\mc71\ folder on my computer!
Please help, I don't know what to do anymore!!!

Jun 27 '08 #1
Share this Question
Share on Google+
46 Replies


P: n/a
In article <31****************@aioe.org>,
Kenny O'Clock <no****@nospam.invalidwrote:
>This came up in a job interview, what is the output of the program
below?
1: #include <stdio.h>
2: void main()
3: {
4: int C = 0;
5: printf("C %s C++\n", C == C++ ? "==" : "!=");
6: }
In the expression C == C++,
the variable being incremented is accessed more than once between
sequence points ("except to determine the value to be stored").
That is not permitted, so the result could be anything.
-Usually- the result would be either "C == C++" or "C != C++"
printed out (dependant on the compiler), but the program
could segfault... or, like you found, the -compiler- could fault.
--
"And that's the way it is." -- Walter Cronkite
Jun 27 '08 #2

P: n/a
Kenny O'Clock wrote:
This came up in a job interview, what is the output of the program
below? I tried to compile and run it myself, but my compiler (lcc-win32)
aborts with this errors....

Warning test2.c: 3 old-style function definition for 'main'
Warning test2.c: 3 missing prototype for 'main'
Warning test2.c: 3 '
Error test2.c: 3 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error c:\test\test2.c 3 Compiler error (trap). Stopping compilation
1 error

Here is the program....

1: #include <stdio.h>
2: void main()
3: {
4: int C = 0;
5: printf("C %s C++\n", C == C++ ? "==" : "!=");
6: }

I don't even have a d:\lcc\mc71\ folder on my computer!
Please help, I don't know what to do anymore!!!
In addition to what Walter said, I would like to point you to question
3.2 of the c.l.c FAQ, at http://c-faq.com/expr/evalorder2.html.

--
Pietro Cerutti
Jun 27 '08 #3

P: n/a
In article <OL******************************@giganews.com>,
Pietro Cerutti <gahr_SPAM_gahr_ME_chwrote:
>Kenny O'Clock wrote:
> 5: printf("C %s C++\n", C == C++ ? "==" : "!=");
>In addition to what Walter said, I would like to point you to question
3.2 of the c.l.c FAQ, at http://c-faq.com/expr/evalorder2.html.
Though the impact of that question is a bit reduced because there -is-
a sequence point after the evaluation of C == C++ . That confines
the section of undefined behaviour to be relatively small compared
to typical expressions we see that mix variable accesses with
++ or -- .
--
"Nothing recedes like success." -- Walter Winchell
Jun 27 '08 #4

P: n/a
In article <g1**********@canopus.cc.umanitoba.ca>,
Walter Roberson <ro******@ibd.nrc-cnrc.gc.cawrote:
>In article <OL******************************@giganews.com>,
Pietro Cerutti <gahr_SPAM_gahr_ME_chwrote:
>>Kenny O'Clock wrote:
>> 5: printf("C %s C++\n", C == C++ ? "==" : "!=");
>>In addition to what Walter said, I would like to point you to question
3.2 of the c.l.c FAQ, at http://c-faq.com/expr/evalorder2.html.

Though the impact of that question is a bit reduced because there -is-
a sequence point after the evaluation of C == C++ . That confines
the section of undefined behaviour to be relatively small compared
to typical expressions we see that mix variable accesses with
++ or -- .
Relatively small, perhaps, but still large enough to include all of the
accesses to C in that line of code.
dave

--
Dave Vandervies dj3vande at eskimo dot com
My burning question is this:
"Why do you have some perverse desire to lie to fprintf()?"
--Dann Corbit in comp.lang.c
Jun 27 '08 #5

P: n/a
Walter Roberson said:
In article <OL******************************@giganews.com>,
Pietro Cerutti <gahr_SPAM_gahr_ME_chwrote:
>>Kenny O'Clock wrote:
>> 5: printf("C %s C++\n", C == C++ ? "==" : "!=");
>>In addition to what Walter said, I would like to point you to question
3.2 of the c.l.c FAQ, at http://c-faq.com/expr/evalorder2.html.

Though the impact of that question is a bit reduced because there -is-
a sequence point after the evaluation of C == C++ . That confines
the section of undefined behaviour to be relatively small compared
to typical expressions we see that mix variable accesses with
++ or -- .
Firstly, because the Standard imposes no limits on the implementation with
regard to undefined behaviour, the wayward effect of C == C++ is not
limited to the "section" of code within which it occurs.

Secondly (and I only mention it because nobody else has in the five replies
that I've seen), the program exhibits undefined behaviour in another way,
too, because the return type of main is incorrect.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #6

P: n/a
Richard Heathfield wrote:
Walter Roberson said:
>In article <OL******************************@giganews.com>,
Pietro Cerutti <gahr_SPAM_gahr_ME_chwrote:
>>Kenny O'Clock wrote:
>>> 5: printf("C %s C++\n", C == C++ ? "==" : "!=");
>>In addition to what Walter said, I would like to point you to
question
3.2 of the c.l.c FAQ, at http://c-faq.com/expr/evalorder2.html.

Though the impact of that question is a bit reduced because there
-is- a sequence point after the evaluation of C == C++ . That
confines
the section of undefined behaviour to be relatively small compared
to typical expressions we see that mix variable accesses with
++ or -- .

Firstly, because the Standard imposes no limits on the implementation
with regard to undefined behaviour, the wayward effect of C == C++ is
not limited to the "section" of code within which it occurs.

Secondly (and I only mention it because nobody else has in the five
replies that I've seen), the program exhibits undefined behaviour in
another way, too, because the return type of main is incorrect.
And win-lcc properly warns about this...

Bye, Jojo
Jun 27 '08 #7

P: n/a
Joachim Schmitz said:
Richard Heathfield wrote:
<snip>
>Secondly (and I only mention it because nobody else has in the five
replies that I've seen), the program exhibits undefined behaviour in
another way, too, because the return type of main is incorrect.

And win-lcc properly warns about this...
Implementations are not obliged to diagnose incorrect signatures for main.
If they choose to do so, however, it would be good if they could come up
with some decent diagnostic text. The text given is: "old-style function
definition for 'main'". In fact, there's nothing "old-style" about the
function definition. The problem lies with the return type, and void main
isn't old-style - it's simply *wrong*.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #8

P: n/a
On Wed, 28 May 2008 23:52:36 +0100, Kenny O'Clock <no****@nospam.invalid
wrote:
This came up in a job interview, what is the output of the program
below?
[...]
1: #include <stdio.h>
2: void main()
3: {
4: int C = 0;
5: printf("C %s C++\n", C == C++ ? "==" : "!=");
6: }
I'm sure from the responses you've had you now realise that the program is
an example of how not to write C. I would send the code back to the
interviewers, annotated in red with the problems and explain to them why
it is bad. Maybe (and it's a big maybe) the author *knew* what a load of
tripe the code is and that was part of the test.

Several years ago at interview I was shown some (production) C code and I
pointed out that the use of memcpy for overlapping buffers was undefined..
The interviewer was convinced that memcpy was safe to use it and that
memmove was the unsafe one. Anyway, after the interview, I wrote them a
letter declining a second interview and provided them an extract from the
C Standard where it says memmove must work properly even when its operands
overlap.

--
Martin

Jun 27 '08 #9

P: n/a
Richard Heathfield wrote:
Joachim Schmitz said:
>Richard Heathfield wrote:

<snip>
>>Secondly (and I only mention it because nobody else has in the five
replies that I've seen), the program exhibits undefined behaviour in
another way, too, because the return type of main is incorrect.

And win-lcc properly warns about this...

Implementations are not obliged to diagnose incorrect signatures for
main. If they choose to do so, however, it would be good if they
could come up with some decent diagnostic text. The text given is:
"old-style function definition for 'main'". In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).
Jun 27 '08 #10

P: n/a
"Joachim Schmitz" <no*********@schmitz-digital.dewrote:
Richard Heathfield wrote:
Joachim Schmitz said:
Implementations are not obliged to diagnose incorrect signatures for
main. If they choose to do so, however, it would be good if they
could come up with some decent diagnostic text. The text given is:
"old-style function definition for 'main'". In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).
No, they're not. void wasn't in K&R1 at all; so void main() is an _ISO_
declaration, of a function returning nothing (which is wrong for main())
and taking an unspecified number of arguments. If it had been an
old-style declaration, there would have been no void on either side; it
would have been either

main()
{ ....

(which, due to the default int, is correct, although bad style, for a
main() which takes no command line arguments) or

main()
int argc;
char **argv;
{ ....

Neither of those should, of course, be used today, except when faced
with an overwhelming necessity of porting to outdated systems.

Richard
Jun 27 '08 #11

P: n/a
On May 29, 10:44 am, Martin <m...@b.cwrote:
Several years ago at interview I was shown some (production) C code and I
pointed out that the use of memcpy for overlapping buffers was undefined.
The interviewer was convinced that memcpy was safe to use it and that
memmove was the unsafe one. Anyway, after the interview, I wrote them a
letter declining a second interview and provided them an extract from the
C Standard where it says memmove must work properly even when its operands
overlap.
In many implementations, memcpy (dst, dst + n, count) will behave
exactly like memmove (dst, dst + n, count) if n 0, while memcpy (dst
+ n, dst, count) will usually invoke some rather bizarre behaviour.
That doesn't change the fact that it is undefined behavior, and
relying on this is of course utterly stupid.

For example, a highly optimised version of memcpy intended for a
processor with vector registers could look like this:

size_t i;

if (size % 16 != 0)
{
size_t originalsize = size;
size_t i;
size -= size % 16;
for (i = size; i < originalsize; ++i) dst [i] = src [i];
}

for (i = 0; i < size; i += 16)
"Copy 16 bytes from src + i to dst + i";

Jun 27 '08 #12

P: n/a
Joachim Schmitz said:
Richard Heathfield wrote:
<snip>
>In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).
If that's truly what the message means, it's silly - the compiler is
ignoring a genuine error and instead flagging up perfectly harmless code.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #13

P: n/a
Richard Heathfield wrote:
Joachim Schmitz said:
>Richard Heathfield wrote:

<snip>
>>In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).

If that's truly what the message means, it's silly - the compiler is
ignoring a genuine error and instead flagging up perfectly harmless code.
I wouldn't call it a "genuine error" to use an implementation-
defined extension.

5.1.2.2.1 Program startup
[...] main [...] shall be defined with a return type
of int [...] or in some other implementation-defined
manner.

It's not portable, and the next debutante in the Compiler's
Coming-Out Cotillion is not obliged to dance this particular
dance well or at all, but it's no contravention of C's rules.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #14

P: n/a
Eric Sosman said:
Richard Heathfield wrote:
>Joachim Schmitz said:
>>Richard Heathfield wrote:

<snip>
>>>In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).

If that's truly what the message means, it's silly - the compiler is
ignoring a genuine error and instead flagging up perfectly harmless
code.

I wouldn't call it a "genuine error" to use an implementation-
defined extension.
It's only implementation-defined if it's documented. Is it?

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #15

P: n/a
On Thu, 29 May 2008 11:47:08 +0100, christian.bau
<ch***********@cbau.wanadoo.co.ukwrote:
Nothing wrong with this as an interview question.
True, but I would be interested to know if the interviewer explained to
Kenny the expected result, and used the term 'undefined behaviour' when
doing so.

--
Martin

Jun 27 '08 #16

P: n/a
On Thu, 29 May 2008 21:03:23 +0100, Flash Gordon wrote:
The code in question was:
1: #include <stdio.h>
2: void main()
3: {
4: int C = 0;
5: printf("C %s C++\n", C == C++ ? "==" : "!=");
6: }

Code never gets reviewed at your company?
>. . .

Personally I would not want to work for a company where code like that
would be accepted.
It seems obviously to me that someone is trying to have somebody else do
his assignment. :-)

--
Tong (remove underscore(s) to reply)
http://xpt.sourceforge.net/techdocs/
http://xpt.sourceforge.net/tools/
Jun 27 '08 #17

P: n/a
On Thu, 29 May 2008 12:17:21 +0000, Richard Heathfield <rj*@see.sig.invalidwrote:
>Joachim Schmitz said:
>Richard Heathfield wrote:

<snip>
>>In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).

If that's truly what the message means, it's silly - the compiler is
ignoring a genuine error and instead flagging up perfectly harmless code.
You are ignoring third warning. If I add prototype for main like below,
compiler only issues one warning

#include <stdio.h>
void main(int argc, char **argv)
{
int C = 0;
printf("C %s C++\n", C == C++ ? "==" : "!=");
}

$ make foo9.exe
lc -ansic -pedantic -A -shadows -unused -O -c foo9.c -o foo9.obj
Warning foo9.c: 3 '
Error foo9.c: 3 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error c:\tmp\clc\foo9.c 3 Compiler error (trap). Stopping compilation
1 error
make: *** [foo9.obj] Error 1

Perhaps there is bug.

Jun 27 '08 #18

P: n/a
On May 29, 3:18*pm, Three Headed Monkey <four_headed_mon...@yahoo.com>
wrote:
On Thu, 29 May 2008 12:17:21 +0000, Richard Heathfield <r...@see.sig.invalidwrote:
Joachim Schmitz said:
Richard Heathfield wrote:
<snip>
>In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).
If that's truly what the message means, it's silly - the compiler is
ignoring a genuine error and instead flagging up perfectly harmless code.

You are ignoring third warning. If I add prototype for main like below,
compiler only issues one warning

* #include <stdio.h>
* void main(int argc, char **argv)
* {
* * int C = 0;
* * printf("C %s C++\n", C == C++ ? "==" : "!=");
* }

$ make foo9.exe
lc -ansic -pedantic -A -shadows -unused -O -c foo9.c -o foo9.obj
Warning foo9.c: 3 *'
Error foo9.c: 3 *compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error c:\tmp\clc\foo9.c 3 Compiler error (trap). Stopping compilation
1 error
make: *** [foo9.obj] Error 1

Perhaps there is bug.
Refusing to compile code that exhibits undefined behavior seems more
like a feature than a bug to me.
In fact, I wish that all my compilers would do that. (At least in the
cases where undefined behavior can be repaired).
Jun 27 '08 #19

P: n/a
On Fri, 30 May 2008, Three Headed Monkey wrote:
>On Thu, 29 May 2008 12:17:21 +0000, Richard Heathfield <rj*@see.sig.invalidwrote:
>>Joachim Schmitz said:
>>Richard Heathfield wrote:

<snip>
>>>In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).

If that's truly what the message means, it's silly - the compiler is
ignoring a genuine error and instead flagging up perfectly harmless code.

You are ignoring third warning. If I add prototype for main like below,
compiler only issues one warning

#include <stdio.h>
void main(int argc, char **argv)
{
int C = 0;
printf("C %s C++\n", C == C++ ? "==" : "!=");
}

$ make foo9.exe
lc -ansic -pedantic -A -shadows -unused -O -c foo9.c -o foo9.obj
Warning foo9.c: 3 '
Error foo9.c: 3 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error c:\tmp\clc\foo9.c 3 Compiler error (trap). Stopping compilation
1 error
make: *** [foo9.obj] Error 1

Perhaps there is bug.
I may be misremembering but I think this is a limitation in the
free version and you need to buy a premium commercial license to
be able to use 'void main()' in lcc-win.

Jun 27 '08 #20

P: n/a
Sandpaper Supplier for Pinocchio wrote:
On Fri, 30 May 2008, Three Headed Monkey wrote:
>On Thu, 29 May 2008 12:17:21 +0000, Richard Heathfield <rj*@see.sig.invalidwrote:
>>Joachim Schmitz said:

Richard Heathfield wrote:
<snip>

In fact, there's nothing
"old-style" about the function definition. The problem lies with the
return type, and void main isn't old-style - it's simply *wrong*.
The empty parens are old style, vs. main(void).
If that's truly what the message means, it's silly - the compiler is
ignoring a genuine error and instead flagging up perfectly harmless code.
You are ignoring third warning. If I add prototype for main like below,
compiler only issues one warning

#include <stdio.h>
void main(int argc, char **argv)
{
int C = 0;
printf("C %s C++\n", C == C++ ? "==" : "!=");
}

$ make foo9.exe
lc -ansic -pedantic -A -shadows -unused -O -c foo9.c -o foo9.obj
Warning foo9.c: 3 '
Error foo9.c: 3 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error c:\tmp\clc\foo9.c 3 Compiler error (trap). Stopping compilation
1 error
make: *** [foo9.obj] Error 1

Perhaps there is bug.

I may be misremembering but I think this is a limitation in the
free version and you need to buy a premium commercial license to
be able to use 'void main()' in lcc-win.
LOL!

--
pete
Jun 27 '08 #21

P: n/a
user923005 wrote:
>
Refusing to compile code that exhibits undefined behavior seems more
like a feature than a bug to me.
In fact, I wish that all my compilers would do that. (At least in the
cases where undefined behavior can be repaired).
IMHO that's an unfortunate wish. Here, for example,
is the start of a program that exhibits undefined behavior:

#include <unistd.h>
...

Do you really want the compiler to reject it?

As the Rationale puts it, "the ability to write machine-
specific code is one of the strengths of C." If C were
*unable* to poke I/O registers, *unable* to call dlsym() and
convert a void* to a function pointer, *unable* to overflow
an `int' without trapping, C would be far less useful than
it actually is.

There is an unfortunate tendency among novice C programmers
to resort to undefined or implementation-defined behavior when
portable alternatives exist if one is informed enough and
careful enough to use them. But sometimes C is used to achieve
effects that simply aren't portable, that rely on behavior left
undefined by the C Standard but defined by the platforms of
interest. Such programs do compile, and should compile, even
though the C Standard does not define their behavior.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #22

P: n/a
Three Headed Monkey said:

<snip>
You are ignoring third warning.
The third warning, as originally reported, was a single apostrophe, and
that's fairly easy to ignore.
If I add prototype for main like below,
compiler only issues one warning

#include <stdio.h>
void main(int argc, char **argv)
{
int C = 0;
printf("C %s C++\n", C == C++ ? "==" : "!=");
}

$ make foo9.exe
lc -ansic -pedantic -A -shadows -unused -O -c foo9.c -o foo9.obj
Warning foo9.c: 3 '
I note that the single apostrophe remains even here. I'm not sure what "lc"
means by this apostrophe, but it's a legal diagnostic message. Perhaps it
means "this code is so screwed I just give up on the whole thing", which
would at least make sense.
Error foo9.c: 3 compiler error in d:\lcc\mc71\types.c--assertion failure
at line 868 Error c:\tmp\clc\foo9.c 3 Compiler error (trap). Stopping
compilation 1 error
make: *** [foo9.obj] Error 1

Perhaps there is bug.
Perhaps there is, but you haven't shown this. The cited program exhibits
undefined behaviour, so the implementation is allowed to do anything it
likes with it - and since I don't see any syntax errors or constraint
violations, I see no requirement for any message whatsoever. For the
compiler to have a bug that is relevant to the above code, it would surely
have to be exhibiting (or harbouring) some inappropriate behaviour when
given that code. But since the Standard allows all behaviours for such
code, it is hard to see how it could be used to demonstrate a bug in the
implementation.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #23

P: n/a
Eric Sosman <es*****@ieee-dot-org.invalidwrites:
user923005 wrote:
>Refusing to compile code that exhibits undefined behavior seems more
like a feature than a bug to me.
In fact, I wish that all my compilers would do that. (At least in the
cases where undefined behavior can be repaired).

IMHO that's an unfortunate wish. Here, for example,
is the start of a program that exhibits undefined behavior:

#include <unistd.h>
...

Do you really want the compiler to reject it?

As the Rationale puts it, "the ability to write machine-
specific code is one of the strengths of C." If C were
*unable* to poke I/O registers, *unable* to call dlsym() and
convert a void* to a function pointer, *unable* to overflow
an `int' without trapping, C would be far less useful than
it actually is.
Sure, but there's undefined behavior and then there's undefined
behavior.

There are plenty of constructs whose behavior the standard doesn't
define that can nevertheless be useful in non-portable code.

On the other hand, some constructs, such as ``C == C++'' or
``i = i++'' are, in a sense, more purely undefined, to the extent that
they should never appear in normal C code. Regardless of the
portability of the program, there's always a better way to expression
whatever the intent was.

For such constructs, I certainly have no problem with a compiler
warning about them, or even rejecting the translation unit *if* it can
prove that the code will always be executed.

The tricky (and perhaps undecidable) part is determining which
instances of UB are potentially ok and which are not.

(On the other hand, the way in which the particular compiler
terminated, with an internal assertion failure, indicates a bug in
that compiler -- though the standard doesn't say what a diagnostic has
to look like.)

[...]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #24

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Three Headed Monkey said:
[...]
>Error foo9.c: 3 compiler error in d:\lcc\mc71\types.c--assertion failure
at line 868 Error c:\tmp\clc\foo9.c 3 Compiler error (trap). Stopping
compilation 1 error
make: *** [foo9.obj] Error 1

Perhaps there is bug.

Perhaps there is, but you haven't shown this. The cited program
exhibits undefined behaviour, so the implementation is allowed to do
anything it likes with it - and since I don't see any syntax errors
or constraint violations, I see no requirement for any message
whatsoever. For the compiler to have a bug that is relevant to the
above code, it would surely have to be exhibiting (or harbouring)
some inappropriate behaviour when given that code. But since the
Standard allows all behaviours for such code, it is hard to see how
it could be used to demonstrate a bug in the implementation.
I think you're using a far too narrow definition of "bug".

The way I use the term, a failure to conform to the standard (on the
part of an implementation that claims to conform to the standard) is
certainly a bug, but many other things are bugs as well. Responding
to undefined behavior by blowing up rather than by printing a proper
error message, though it doesn't violate the standard, is, in my
opinion, a bug.

Also, I suspect (though I have no direct evidence of this) that the
compiler would react the same way to the same code in a function
that's never called. In such a case, the standard doesn't permit the
compiler to reject the translation unit.

(BTW, I'm not trying to pick on lcc-win here.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #25

P: n/a
On May 29, 6:29*pm, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
user923005 wrote:
Refusing to compile code that exhibits undefined behavior seems more
like a feature than a bug to me.
In fact, I wish that all my compilers would do that. (At least in the
cases where undefined behavior can be repaired).

* * *IMHO that's an unfortunate wish. *Here, for example,
is the start of a program that exhibits undefined behavior:

* * * * #include <unistd.h>
* * * * ...

Do you really want the compiler to reject it?
Can the compiler do anything about it?

In the case of:

i = i++;

It can.

In the second case, it can't.
* * *As the Rationale puts it, "the ability to write machine-
specific code is one of the strengths of C." *If C were
*unable* to poke I/O registers, *unable* to call dlsym() and
convert a void* to a function pointer, *unable* to overflow
an `int' without trapping, C would be far less useful than
it actually is.

* * *There is an unfortunate tendency among novice C programmers
to resort to undefined or implementation-defined behavior when
portable alternatives exist if one is informed enough and
careful enough to use them. *But sometimes C is used to achieve
effects that simply aren't portable, that rely on behavior left
undefined by the C Standard but defined by the platforms of
interest. *Such programs do compile, and should compile, even
though the C Standard does not define their behavior.
I agree that:
1. It is far better to use fully portable code if possible.
2. Almost every real project invokes undefined behavior at some point
3. Most of the time, we do not even recognize that the behavior is
undefined
4. Even when we recognize that the behavior is undefined, we probably
can't do anything about it (e.g. unistd.h or windows.h)

There are also rare cases where we know for sure that:
1. The behavior is undefined
2. The undefined behavior is undesirable

such as:
i = i++; /* There is literally no sensible reason imaginable to do
this. */

In these few cases, I think a very sensible solution is to issue an
error message and refuse to create a binary.
Jun 27 '08 #26

P: n/a
Keith Thompson said:
Responding to undefined behavior by blowing up rather than by
printing a proper error message, though it doesn't violate
the standard, is, in my opinion, a bug.
But what if the implementation *documents* such responses? :-)
(BTW, I'm not trying to pick on lcc-win here.)
In my view, the blame rests squarely on the shoulders of the OP's program.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #27

P: n/a
On Fri, 30 May 2008 04:12:46 +0100, Keith Thompson <ks***@mib.orgwrote:
Sure, but there's undefined behavior and then there's undefined
behavior.
That seems to dilute somewhat the exhortations I read about undefined
behaviour being intolerable in all its manifestations. Now it seems there
is a continuum of undefined behaviours ranging from the tolerable (and
dare I say "acceptable") to the unacceptable. If not a continuum, then at
least split between tolerable and unacceptable.

Keith, have I read too much into your comment?

--
Martin

Jun 27 '08 #28

P: n/a
Martin said:
On Fri, 30 May 2008 04:12:46 +0100, Keith Thompson <ks***@mib.orgwrote:
>Sure, but there's undefined behavior and then there's undefined
behavior.

That seems to dilute somewhat the exhortations I read about undefined
behaviour being intolerable in all its manifestations. Now it seems there
is a continuum of undefined behaviours ranging from the tolerable (and
dare I say "acceptable") to the unacceptable. If not a continuum, then at
least split between tolerable and unacceptable.

Keith, have I read too much into your comment?
You may have read too much into the party line of clc polemic. Keith
rightly draws a distinction between code that exhibits undefined behaviour
because it uses a machine-specific tool/technique/function that is
necessary for the purposes of the program to be fulfilled, and code that
exhibits undefined behaviour because the programmer doesn't know spit
about C. (I trust that you will read that sentence in the spirit in which
it was intended, rather than take it /too/ literally.)

Writing code of the first kind is very sensible, but is merely off-topic in
comp.lang.c (which doesn't address platform specifics). Writing code of
the second kind is simply wrong.

Telling the difference between the two is not something that many clcers
are particularly skilled at doing, but it is quite clear that Keith
understands the difference.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #29

P: n/a
On Fri, 30 May 2008 12:13:05 +0100, Richard Heathfield
<rj*@see.sig.invalidwrote:
You may have read too much into the party line of
clc polemic. Keith rightly draws a distinction
between code that exhibits undefined behaviour
because it uses a machine-specific tool/technique/function
that is necessary for the purposes of the program to be
fulfilled,
The key word there, I think, is "exhibits". I was taking 'undefined
behaviour' to mean the manisfestation of the result from "... erroneous
program construct or of erroneous data" (ISO/IEC 9899:1999 (E) 3.4.3).

But, the ellipsis hides the important phrase "use of a nonportable or ..."

So undefined behaviour can be caused by non-portable C. I also note that
the cited paragraph's note says that an undefined behaviour can include
"behaving during translation or program execution in a documented manner
characteristic of the environment". This changes the view of undefined
behaviour I've seen promulgated that regards it as a heinous crime against
C, and is to be extirpated at all costs.

and code that exhibits undefined behaviour
because the programmer doesn't know spit about C. (I trust
that you will read that sentence in the spirit in which
it was intended, rather than take it /too/ literally.)
All I can say is that I think I know a lot about C, but I learn something
more about it each day ...

Writing code of the first kind is very sensible, but is merely
off-topic in comp.lang.c (which doesn't address platform
specifics). Writing code of the second kind is simply wrong.

Telling the difference between the two is not something that many clcers
are particularly skilled at doing, but it is quite clear that Keith
understands the difference.
Now I know about the difference, I will look for it. Thanks for the
response.

--
Martin

Jun 27 '08 #30

P: n/a
Richard Heathfield wrote:
Three Headed Monkey said:

<snip>
>You are ignoring third warning.

The third warning, as originally reported, was a single apostrophe, and
that's fairly easy to ignore.
>If I add prototype for main like below,
compiler only issues one warning

#include <stdio.h>
void main(int argc, char **argv)
{
int C = 0;
printf("C %s C++\n", C == C++ ? "==" : "!=");
}

$ make foo9.exe
lc -ansic -pedantic -A -shadows -unused -O -c foo9.c -o foo9.obj
Warning foo9.c: 3 '

I note that the single apostrophe remains even here. I'm not sure what
"lc" means by this apostrophe, but it's a legal diagnostic message.
Perhaps it means "this code is so screwed I just give up on the whole
thing", which would at least make sense.
That got me to do some experiments.

The good thing is, lcc-win rejects all return types with the
exception of `int' and equivalents (e.g., `signed' or `signed int',
but not `unsigned' or `unsigned int' or 'long'), e.g. --

float main(int argc, char **argv) { return 3.1415927f; }

wine lc -A -ansic -pedantic -O -c foo.c
Warning foo.c: 1 '
Error foo.c: 1 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error z:\home\tpot\src\CLC\foo.c 1 Compiler error (trap). Stopping compilation
1 error

Interestingly, the following programs are also rejected with
exactly the same diagnostics --

int main(const int argc, char **argv) { return 0; }

int main(int argc) { return 0; }

wine lc -A -ansic -pedantic -O -c foo.c
Warning foo.c: 1 '
Error foo.c: 1 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error z:\home\tpot\src\CLC\foo.c 1 Compiler error (trap). Stopping compilation
1 error

More interestingly, the next program is accepted --

float int unsigned signed int main(int argc, char **argv) { return 0; }

wine lc -A -ansic -pedantic -O -c foo.c
Warning foo.c: 1 multiple use of 'int'
Warning foo.c: 1 multiple use of 'signed'
Warning foo.c: 1 multiple use of 'int'
Warning foo.c: 1 parameter 'pointer to pointer to char argv' is not referenced
Warning foo.c: 1 parameter 'int argc' is not referenced
0 errors, 4 warnings
wine lc foo.obj -o foo.exe

wine foo.exe
echo $?
0

[snip]

--
T.Pot.

Jun 27 '08 #31

P: n/a
teapot <te*@pot.invalidwrites:
[...]
[...]
The good thing is, lcc-win rejects all return types with the
exception of `int' and equivalents (e.g., `signed' or `signed int',
but not `unsigned' or `unsigned int' or 'long'), e.g. --

float main(int argc, char **argv) { return 3.1415927f; }

wine lc -A -ansic -pedantic -O -c foo.c
Warning foo.c: 1 '
Error foo.c: 1 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error z:\home\tpot\src\CLC\foo.c 1 Compiler error (trap). Stopping compilation
1 error
Any time a compiler dies with an internal error (in this case, an
assertion failure), that's a bug in the compiler, even if it only
chokes on invalid programs. It doesn't violate standard, but it's
still a bug, at least as I use the word "bug". In this case, the
compiler *should* issue an error message that refers to the problem in
the code.

This is a QoI (quality of implementation) issue, not a conformance
issue.

(Let me emphasize again that I'm not picking on lcc-win.)
Interestingly, the following programs are also rejected with
exactly the same diagnostics --

int main(const int argc, char **argv) { return 0; }

int main(int argc) { return 0; }

wine lc -A -ansic -pedantic -O -c foo.c
Warning foo.c: 1 '
Error foo.c: 1 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error z:\home\tpot\src\CLC\foo.c 1 Compiler error (trap). Stopping compilation
1 error
Again, a bug.
More interestingly, the next program is accepted --

float int unsigned signed int main(int argc, char **argv) { return 0; }

wine lc -A -ansic -pedantic -O -c foo.c
Warning foo.c: 1 multiple use of 'int'
Warning foo.c: 1 multiple use of 'signed'
Warning foo.c: 1 multiple use of 'int'
Warning foo.c: 1 parameter 'pointer to pointer to char argv' is not referenced
Warning foo.c: 1 parameter 'int argc' is not referenced
0 errors, 4 warnings
wine lc foo.obj -o foo.exe

wine foo.exe
echo $?
0
That program violates at least one constraint. An implementation
isn't required to reject a program that violates a constraint; it's
only required to issue at least one diagnostic. The warnings qualify
as diagnostics. (I'm a little surprised that the compiler treats this
particular problem as a warning rather than an error, but the standard
makes no distinction between warnings and errors.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #32

P: n/a
Martin <m@b.cwrites:
On Fri, 30 May 2008 04:12:46 +0100, Keith Thompson <ks***@mib.orgwrote:
>Sure, but there's undefined behavior and then there's undefined
behavior.

That seems to dilute somewhat the exhortations I read about undefined
behaviour being intolerable in all its manifestations. Now it seems
there is a continuum of undefined behaviours ranging from the
tolerable (and dare I say "acceptable") to the unacceptable. If not a
continuum, then at least split between tolerable and unacceptable.

Keith, have I read too much into your comment?
On further thought, I think I've come up with a clearer way to express
this.

Here in comp.lang.c, the phrase "undefined behavior" usually refers to
behavior that is not defined by the C standard (because that's how the
C standard defines the term).

In real-world programming, this is often too narrow. The distinction
I'm making is among the following:

1. Behavior that's defined by the C standard.

2. Behavior that's not defined by the C standard, but that is defined
by something else (e.g., by POSIX, by a particular implementation,
by a third-party library).

3. Behavior that is not, or that should not be, defined by *anything*.

Implementation-defined behavior (i.e., behavior that the C standard
doesn't define, but that it requires each implementation to define) is
somewhere between 1 and 2. Unspecified behavior is probably somewhere
between 2 and 3 (but it's not *really* a linear scale).

Class 3 covers things like ``i = i++;'' and ``i == i++'', as well as
stepping outside the bounds of an array, accessing to an object
outside its lifetime, reading an uninitialized object, defererencing a
null pointer, and so forth.

Roughly speaking, things in class 1 are topical in this newsgroup,
things in class 2 may be perfectly appropriate programming practices
(for code that doesn't need to be portable) but are usually more
topical in some other newsgroup than in this one, and things in class
3 should be avoided altogether.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #33

P: n/a
Martin wrote:
[...]
So undefined behaviour can be caused by non-portable C.
Tautologically, portable C cannot cause it.
I also note that
the cited paragraph's note says that an undefined behaviour can include
"behaving during translation or program execution in a documented manner
characteristic of the environment". This changes the view of undefined
behaviour I've seen promulgated that regards it as a heinous crime
against C, and is to be extirpated at all costs.
The most important thing about UB is not to avoid it, but
to be aware of it. When you engage in UB or even in IDB, you
limit the portability of your code -- that is, you increase the
difficulty and expense of porting it to a new environment. If
the history of computation teaches us anything, it teaches us
that new environments crowd upon us faster than even the most
futuristic of us anticipate, so we port more than planned for.

Opinion #1: A good engineer, weighing the competing goals
of portability, time to market, ease of development, and a host
of other issues may well decide to sacrifice some degree of
portability in favor of some other goal. There is absolutely
nothing wrong with -- and everything laudable about -- such a
considered choice. Trade-offs are what engineering is about.

Opinion #2: When portability is sacrificed out of laziness
or ignorance, it means the "engineer" is deficient. Considered
choices are one thing; superstition is another.
All I can say is that I think I know a lot about C, but I learn
something more about it each day ...
One lifetime is not enough to master the C language.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #34

P: n/a
On Thu, 29 May 2008 10:14:39 UTC, "Joachim Schmitz"
<no*********@schmitz-digital.dewrote:
The empty parens are old style, vs. main(void).
True, but void main() is not legal because main requires a return type
of int even in K&R C. There is no C where void main() is legal.
--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2R Deutsch ist da!
Jun 27 '08 #35

P: n/a
Herbert Rosenau wrote:
On Thu, 29 May 2008 10:14:39 UTC, "Joachim Schmitz"
<no*********@schmitz-digital.dewrote:
>The empty parens are old style, vs. main(void).

True, but void main() is not legal because main requires a return type
of int even in K&R C. There is no C where void main() is legal.
void main() is not illegal, it is allowed to an implementation to provides
it as an extension.

Elsethread someone menioned that win-lcc provides that extension in it's
commercial version 8-)

Bye, Jojo
Jun 27 '08 #36

P: n/a
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
On Thu, 29 May 2008 10:14:39 UTC, "Joachim Schmitz"
<no*********@schmitz-digital.dewrote:
>The empty parens are old style, vs. main(void).

True, but void main() is not legal because main requires a return type
of int even in K&R C. There is no C where void main() is legal.
Depends on what you mean by "legal". The standard specifically
permits implementations to permit alternate declarations of main,
including ones where it returns void. Even on implementations where
it's not specifically permitted, "void main()" merely invokes
undefined behavior, so a compiler is not required to reject or even
diagnose it.

Of course that's no excuse for using "void main()" in a program (or,
worse yet, in a book) -- unless it's for a freestanding implementation
that specifically documents that form.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #37

P: n/a
Dan
What do you mean C is not equal to C++ ?
Thats the point of the question, you are meant to get C==C++ and from the
answer you realise you are stupid because the program doesn't work.
Jun 27 '08 #38

P: n/a
"Joachim Schmitz" <no*********@schmitz-digital.dewrote:
Herbert Rosenau wrote:
On Thu, 29 May 2008 10:14:39 UTC, "Joachim Schmitz"
The empty parens are old style, vs. main(void).
True, but void main() is not legal because main requires a return type
of int even in K&R C. There is no C where void main() is legal.
void main() is not illegal, it is allowed to an implementation to provides
it as an extension.
True as far as it goes, but it leaves me wondering why nobody ever uses
this as an excuse to write

struct mainreturn { int status; int error; float runtime; } main(void)

Richard
Jun 27 '08 #39

P: n/a
Three Headed Monkey <fo****************@yahoo.comwrote:
You are ignoring third warning. If I add prototype for main like below,
compiler only issues one warning

#include <stdio.h>
void main(int argc, char **argv)
{
int C = 0;
printf("C %s C++\n", C == C++ ? "==" : "!=");
}

$ make foo9.exe
lc -ansic -pedantic -A -shadows -unused -O -c foo9.c -o foo9.obj
Warning foo9.c: 3 '
Error foo9.c: 3 compiler error in d:\lcc\mc71\types.c--assertion failure at line 868
Error c:\tmp\clc\foo9.c 3 Compiler error (trap). Stopping compilation
1 error
make: *** [foo9.obj] Error 1

Perhaps there is bug.
There most certainly is a bug. Several, in fact.

First, there are the obvious bugs in your code. Three, in all.

But there is also a bug in _either_ your compiler _or_ the way you have
installed it. That error message is clearly faulty. Strictly speaking
it's within the limits of the Standard, but then, so would "?" be.
However, I cannot imagine that any compiler writer would consider the
above to be a reasonable reaction to either void main() _or_ C==C++; and
as a compiler user, I certainly do not consider it reasonable.

If this broken message is as it was intended, that's a bug in the design
of the compiler. If it is not as was intended, but occurs because
there's a bug in the compiler itself, that's, surprise, a bug in the
execution of the compiler. If it is not due to the way the compiler was
written, but because you have one version of the compiler itself with
another version of its headers; or one compiler with the libraries of
another (more likely under Unix, but possible); or something similar,
that's a bug in the installation of the compiler.
I can't tell which is the case, but I'd be surprised if it did not turn
out to be one of those three. In the first two cases, the compiler
writer is at fault, and should remedy this; in the last case, whoever
installed it (presumably yourself) is at fault, and a clean reinstall
should fix the problem.

Richard
Jun 27 '08 #40

P: n/a
On Sat, 31 May 2008 09:14:54 +0100, Keith Thompson <ks***@mib.orgwrote:
The standard specifically permits implementations
to permit alternate declarations of main,
including ones where it returns void.
When 'The Standard' is referred to on clc, does that indicate the C99
Standard? I must admit, I haven't delved into it because I'm not likely to
use a conformant compiler, and in my job I use C89.

If 'The Standard' means C99, is the permission to allow alternate return
types for main new to that?

--
Martin

Jun 27 '08 #41

P: n/a
Martin said:
On Sat, 31 May 2008 09:14:54 +0100, Keith Thompson <ks***@mib.orgwrote:
>The standard specifically permits implementations
to permit alternate declarations of main,
including ones where it returns void.

When 'The Standard' is referred to on clc, does that indicate the C99
Standard?
It depends on who you talk to, really. Some people insist on C99 as the de
jure standard (which, of course, it is), whereas others insist on C90 as
the de facto standard (which, of course, it is). Normally, if it matters,
a clueful subscriber will make it clear which one he or she means.
I must admit, I haven't delved into it because I'm not likely
to use a conformant compiler, and in my job I use C89.
Then you are very likely using a conforming compiler! That is, one that
conforms to C89 (or C90, as some people call it.)
If 'The Standard' means C99, is the permission to allow alternate return
types for main new to that?
Yes. What's more, the alternate types are implementation-defined. Just
because one implementation documents (and thus permits the use of) const
struct tm ***main(), that doesn't mean it won't crash your machine when
compiled under some other implementation.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #42

P: n/a
Martin wrote:
On Sat, 31 May 2008 09:14:54 +0100, Keith Thompson <ks***@mib.org>
wrote:
>The standard specifically permits implementations
to permit alternate declarations of main,
including ones where it returns void.

When 'The Standard' is referred to on clc, does that indicate the C99
Standard? I must admit, I haven't delved into it because I'm not
likely to use a conformant compiler, and in my job I use C89.
Strictly speaking yes. There is only one currently effective C standard
and that's the 1999 one (ISO 9899:1999). But in practise the language
as defined by the previous standard, ISO 9899:1990, also called C89 or
C90 or ANSI C (the first and last designations are not strictly
accurate), is used more often than that defined ISO 9899:1999, with
amendments from 1995 incorporated.

So I suppose the consensus is that when the term "the standard" used
without any other qualifiers it refers to the currently effective
standard document, while one would use appropriate qualifiers (for
example "the C89 standard" or "the C90 standard" etc.) to designate
earlier standards.

In fact a dialect of "pre-ANSI" C called "K&R C" is also, by consensus,
topical here, though I personally know only C as defined by the 1990
and 1999 standards.
If 'The Standard' means C99, is the permission to allow alternate
return types for main new to that?
AFAICS, yes.

Jun 27 '08 #43

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Martin said:
[...]
>If 'The Standard' means C99, is the permission to allow alternate return
types for main new to that?

Yes. What's more, the alternate types are implementation-defined. Just
because one implementation documents (and thus permits the use of) const
struct tm ***main(), that doesn't mean it won't crash your machine when
compiled under some other implementation.
The *explicit* permission to allow alternate return types for main is
new in C99. But IMHO, that clause is redundant. Both the C90 and C99
standards explicitly allow extensions. Even if that weren't the case,
the standard doesn't define the behavior of main returning a type
other than int -- which means that an implementation is free to do so.

But, at least for hosted implementations, there's very little reason
to support return types other than int, and less reason to use return
types other than int.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #44

P: n/a
Keith Thompson <ks***@mib.orgwrites:
[...]
But, at least for hosted implementations, there's very little reason
to support return types other than int, and less reason to use return
types other than int.
On re-reading that, it's not as clear as I thought it would be.

What I meant was that there's very little reason for compilers to
support return types (for main, obviously) other than int, and even
less reason for programmers to use return types other than int.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #45

P: n/a
Keith Thompson <ks***@mib.orgwrote:
>
The *explicit* permission to allow alternate return types for main is
new in C99. But IMHO, that clause is redundant.
It isn't quite redundant because making it implementation defined
requires the implementation to document it.

-- Larry Jones

Start tying the sheets together. We'll go out the window. -- Calvin
Jun 27 '08 #46

P: n/a
la************@siemens.com said:
Keith Thompson <ks***@mib.orgwrote:
>>
The *explicit* permission to allow alternate return types for main is
new in C99. But IMHO, that clause is redundant.

It isn't quite redundant because making it implementation defined
requires the implementation to document it.
C89 requires implementations to document all extensions. See 1.7
Compliance: "An implementation shall be accompanied by a document that
defines all implementation-defined characteristics and all extensions."

This isn't a constraint, so no diagnostic message is required if the
implementation fails to document all extensions, but an implementation
that fails in this way invokes undefined behaviour. Or, conversely, you
could argue that if the implementation is conforming and the supposed
extension isn't documented, it isn't an extension after all.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #47

This discussion thread is closed

Replies have been disabled for this discussion.