|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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 , I don't know what to do anymore!!! |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
"Kenny O'Clock" <nospam@nospam.invalid> wrote in message
news:3167502.MWURcNyiUU@aioe.org... > > 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 , I don't know what to do anymore!!! You should have told the interviewer that you need a valid program in order to make a proper analysis. Then turn the tables and ask him if he sees anything wrong with the program as-is... |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
In article <3167502.MWURcNyiUU@aioe.org>,
Kenny O'Clock <nospam@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: } 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 |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
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 , 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 |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
"Kenny O'Clock" <nospam@nospam.invalid> wrote in message
news:3167502.MWURcNyiUU@aioe.org... > > 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 , I don't know what to do anymore!!! C:\tmp>splint foo.c Splint 3.1.1 --- 12 Mar 2007 foo.c(2,6): Function main declared to return void, should return int The function main does not match the expected type. (Use -maintype to inhibit warning) foo.c: (in function main) foo.c(5,30): Expression has undefined behavior (value of left operand C is modified by right operand C++): C == C++ Code has unspecified behavior. Order of evaluation of function parameters or subexpressions is not defined, so if a value is used and modified in different places not separated by a sequence point constraining evaluation order, then the result of the expression is unspecified. (Use -evalorder to inhibit warning) Finished checking --- 2 code warnings The correct answer is: This program might output something or it might not. It could (according to an expert analysis of the C language standard) cause a demon to come flying out of your nose. P.S. You didn't want to work there anyway, unless it is only those performing interviews who are incompetent nitwits. ** Posted from http://www.teranews.com ** |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
In article <OLGdnY9fnLuybKDVnZ2dneKdnZydnZ2d@giganews.com>,
Pietro Cerutti <gahr_SPAM_gahr_ME_ch> wrote: >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 |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
In article <g1l7jg$aln$1@canopus.cc.umanitoba.ca>,
Walter Roberson <roberson@ibd.nrc-cnrc.gc.ca> wrote: >In article <OLGdnY9fnLuybKDVnZ2dneKdnZydnZ2d@giganews.com>, >Pietro Cerutti <gahr_SPAM_gahr_ME_ch> wrote: >>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 |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Walter Roberson said:
> In article <OLGdnY9fnLuybKDVnZ2dneKdnZydnZ2d@giganews.com>, > Pietro Cerutti <gahr_SPAM_gahr_ME_ch> wrote: >>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 |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Richard Heathfield wrote:
> Walter Roberson said: > >> In article <OLGdnY9fnLuybKDVnZ2dneKdnZydnZ2d@giganews.com>, >> Pietro Cerutti <gahr_SPAM_gahr_ME_ch> wrote: >>> 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 |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
> I don't even have a d:\lcc\mc71\ folder on my computer! > Please , I don't know what to do anymore!!! I give questions like that just to seperate who is anal and who isn't (and don't employ the anal ones - they are most likly to take 10 times as long to write the same page code that no one is ever going to read again). And just incase you really are dumb, C is not equal to C++. |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
"Dan" <voids@sometwher.world> writes:
>> I don't even have a d:\lcc\mc71\ folder on my computer! >> Please , I don't know what to do anymore!!! > > I give questions like that just to seperate who is anal and who isn't (and > don't employ the anal ones - they are most likly to take 10 times as long to > write the same page code that no one is ever going to read again). > And just incase you really are dumb, C is not equal to C++. What do you mean C is not equal to C++ ? |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
On Wed, 28 May 2008 23:52:36 +0100, Kenny O'Clock <nospam@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 |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
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). |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
"Joachim Schmitz" <nospam.jojo@schmitz-digital.de> wrote:
> 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 |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
On May 29, 12:04 am, "Chris Thomasson" <cris...@comcast.net> wrote:
> You should have told the interviewer that you need a valid program in order > to make a proper analysis. Then turn the tables and ask him if he sees > anything wrong with the program as-is... Not at all. The analysis is quite simple: "void main ()" should be changed to "int main ()", possibly better to "int main (void)" to make clear you know that the function has no arguments and that you haven't just forgotten about them. "C == C++" invokes undefined behavior because C is both modified and accessed without an intervening sequence point, so it is impossible to predict what will happen. Likely outcomes are printing "C == C++" or "C != C++", but anything else, including crashing, is also possible and entirely the fault of the programmer who wrote the code. Nothing wrong with this as an interview question. |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
On May 29, 10:44 am, Martin <m...@b.c> wrote:
> 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"; |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
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 esosman@ieee-dot-org.invalid |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
On Thu, 29 May 2008 11:47:08 +0100, christian.bau
<christian.bau@cbau.wanadoo.co.uk> wrote: > 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 |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
Dan wrote, On 29/05/08 09:14:
>> I don't even have a d:\lcc\mc71\ folder on my computer! >> Please , I don't know what to do anymore!!! 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: } > I give questions like that just to seperate who is anal and who isn't (and > don't employ the anal ones - they are most likly to take 10 times as long to > write the same page code that no one is ever going to read again). Code never gets reviewed at your company? > And just incase you really are dumb, C is not equal to C++. The languages in question may be different, but on my system here is prints "C == C++". Amusingly, if I change it to ++C we still get: markg@brenda:~$ cat t.c #include <stdio.h> void main() { int C = 0; printf("C %s C++\n", C == ++C ? "==" : "!="); } markg@brenda:~$ gcc t.c t.c: In function ‘main’: t.c:3: warning: return type of ‘main’ is not ‘int’ markg@brenda:~$ ./a.out C == C++ markg@brenda:~$ Personally I would not want to work for a company where code like that would be accepted. The "void main()" I might put up with, but the clear undefined behaviour for no good reason I would not. I've seen too many instances of C code which needlessly invokes undefined behaviour actually causing programs to behave incorrectly. I've fixed a lot of bugs by gradually increasing the compiler warning level and fixing what it throws up, especially the undefined behaviour. -- Flash Gordon Now a consultant rather than a developer, so I have to stand in front of the customer and apologise of the bugs. |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
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/ |
|
|
|
#24 |
|
Messages: n/a
Hébergeur: |
On Thu, 29 May 2008 12:17:21 +0000, Richard Heathfield <rjh@see.sig.invalid> 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. 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. |
|
|
|
#25 |
|
Messages: n/a
Hébergeur: |
On May 29, 3:18pm, Three Headed Monkey <four_headed_mon...@yahoo.com>
wrote: > On Thu, 29 May 2008 12:17:21 +0000, Richard Heathfield <r...@see.sig.invalid> 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. > > 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). |
|
![]() |
| Outils de la discussion | |
|
|