Yet Another Spinoza Challenge

S

spinoza1111

This test is too simple, but it has its virtues. It avoids C99 issues
and has no trick questions or matters of hermeneutics that I can see.
It is so simple that if you don't get all ten questions right, you
don't know basic C...but that's only my opinion, and I hate C.

http://www.funtrivia.com/playquiz/quiz2530151cf7dd0.html

I got 100%.

I am still searching for a decent objective test. Richard Heathfield
why don't YOU create a C test? Are you scared to?
 
I

Ike Naar

9. In the C language, how does one write the statement, "if i NOT equal
to zero"?

if ( ! i ) - which, again, isn't an option.

Your code tests if ``i'' is equal to zero.
 
T

Tom St Denis

In <[email protected]>, Kenneth Brody
wrote:

<snip>







My instinct says "yes", but I think a strict reading of the Standard
would yield the answer "no". UB is "behavior, upon use of a
nonportable or erroneous program construct or of erroneous data, for
which this International Standard imposes no requirements". Thus,
*all* bets are off, and this includes #error.

But if you really, really, *really* want to know for sure, this is
probably not the best place to ask - comp.std.c might be a better
bet.

Maybe I don't get the question but UB means runtime behaviour not
compile time behaviour.

i = ++i;

May be UB, but it's syntactically valid and should compile to *A*
result [of unspecified behaviour]. So the following #error should
provoke a diagnostic you expect.

Tom
 
J

jameskuyper

Kelsey said:
[snips]

7. Given the definition n = 0; what value does n have? (A) 6
(B) 42
(C) 0
(D) a suffusion of yellow

I'm going with B, on the assumption that n is a pointer,

n can't be a pointer, because "n = 0" was specified to be the
definition. Therefore, this has to be C90 code, relying upon implicit
int.
... and the
architecture uses an oddball value for a null pointer which numerically
would evaluate to 42. Granted, a conforming C program is not supposed to
be able to _tell_ if this is the case...

There are few meaningful restrictions on conforming C programs; that's
not one of them. A strictly conforming program couldn't tell, because
the process of telling would give it different outputs on different
implementations of C. However, the following code has no syntax
errors, violates no constraint, and does not have undefined behavior:

#include <stdlib.h>
int main(void)
{
char *n = 0;
return 42 == (int)n ? EXIT_SUCCESS : EXIT_FAILURE;
}

The standard also says nothing to either mandate or prohibit a
successful exit status for this program.
 
J

jameskuyper

Kenneth said:
Richard Heathfield wrote:
[...]
9. What must the implementation do on encountering a #error directive
in a part of the source code that is not skipped by conditional
inclusion?
(A) ignore it
(B) convert it to a string
(C) fail to translate the preprocessing translation unit
(D) reboot the machine
[...]

Okay, switching back to "in all seriousness" mode...

As I recall, the Standard says that a program which contains UB does not
even need to be properly compiled. Is that correct?

In that case, what about:

=====
extern int i;
void foo(void)
{
i = i++;
}
#error Oops!
=====

Given the UB in "i = i++;", must the compiler still behave according to the
rules, and must it fail to compile the code?

I think that the prohibition on successfully translating such a
program should trump UB. I'm not so sure that this can be derived from
the words of the standard. I'm certain that it's true in this case,
because there's UB only if foo() ever gets called, and at compile time
the compiler can't be certain it will be called; it therefore cannot
use UB as an excuse for ignoring #error. I think that it's less clear
in the case of a program whose behavior is guaranteed to be undefined.
 
K

Keith Thompson

Richard Heathfield said:
7. Given the definition n = 0; what value does n have?
(A) 6
(B) 42
(C) 0
(D) a suffusion of yellow
[...]

Did you mean "int n = 0;"? "n = 0;" is a valid definition in K&R C,
I *think* it may be valid in C90 (I'd have to study the C90 standard
a bit to be sure), and it certainly isn't in C99. I don't think
you intended the question to hang on such a subtle point.
 
K

Keith Thompson

Tom St Denis said:
Maybe I don't get the question but UB means runtime behaviour not
compile time behaviour.

i = ++i;

May be UB, but it's syntactically valid and should compile to *A*
result [of unspecified behaviour]. So the following #error should
provoke a diagnostic you expect.

C99 3.4.3p2:

NOTE Possible undefined behavior ranges from ignoring the
situation completely with unpredictable results, to behaving
during translation or program execution in a documented manner
characteristic of the environment (with or without the issuance of
a diagnostic message), to terminating a translation or execution
(with the issuance of a diagnostic message).

However I don't believe an implementation is required to terminate
translation on seeing "i = ++i;" unless it can prove that the
statement will always be executed.

(I think that most or all implementations will honor the #error
directive even in the presence of inevitable undefined behavior,
but that wasn't the question.)
 
K

Keith Thompson

Kenneth Brody said:
Keith said:
Richard Heathfield said:
7. Given the definition n = 0; what value does n have?
(A) 6
(B) 42
(C) 0
(D) a suffusion of yellow
[...]

Did you mean "int n = 0;"? "n = 0;" is a valid definition in K&R C,
I *think* it may be valid in C90 (I'd have to study the C90 standard
a bit to be sure), and it certainly isn't in C99. I don't think
you intended the question to hang on such a subtle point.

My C compiler, with the default warning level and flags, will compile
this without any diagnostics, and will output "n = 0":

=====
#include <stdio.h>

n = 0;

main()
{
printf("n = %d\n",n);
}
=====

Upping the warning level to the max, I get the following diagnostics:

usenet.c(3) : warning C4431: missing type specifier - int
assumed. Note: C no longer supports default-int
usenet.c(3) : warning C4218: nonstandard extension used : must specify
at least a storage class or a type
usenet.c(6) : warning C4431: missing type specifier - int
assumed. Note: C no longer supports default-int

There are cases where this creates an ambiguity:

int n = 0;

void foo()
{
n = 1; /* Is this an assignment to the file-scope object or
a definition of a new block-scope object? */
}

I presume C90 has a rule that resolves it, but I'm too lazy to look it
up.
 
B

Ben Pfaff

Keith Thompson said:
There are cases where this creates an ambiguity:

int n = 0;

void foo()
{
n = 1; /* Is this an assignment to the file-scope object or
a definition of a new block-scope object? */
}

A declaration must have at least one declaration-specifier, even
in C90, so "n = 1;" is not a declaration. "auto n = 1;" would be
a valid C90 declaration that omits a type specifier.
 
F

Fred Bloggs

(e-mail address removed):

9. What must the implementation do on encountering a #error directive
in a part of the source code that is not skipped by conditional
inclusion?
(A) ignore it
(B) convert it to a string
(C) fail to translate the preprocessing translation unit
(D) reboot the machine

Depends on which C version you use.
Many people still regard C90 as the de-facto C standard (See MISRA-C).
How many strictly conforming C99 implementations exist?

C90 only requires that the #error directive to:
"causes the implementation to produce a diagnostic message that includes
the specified sequence of preprocessing tokens."
There is no requirement for it to "fail to translate the preprocessing
translation unit"

C99 added (in clause 4):
"The implementation shall not successfully translate a preprocessing
translation unit containing a #error preprocessing directive unless it is
part of a group skipped by conditional inclusion."

So in either case the question is wrong.
There is no correct answer for C90 and you don't say if the #error
directive was "encountered" in a section of code that was skipped by
conditional inclusion (you still need to see source line so you can find
the matching #endif)!
 
K

Keith Thompson

Ben Pfaff said:
A declaration must have at least one declaration-specifier, even
in C90, so "n = 1;" is not a declaration. "auto n = 1;" would be
a valid C90 declaration that omits a type specifier.

Ok, perhaps I was thinking of (pre-ANSI) K&R C.

I may still be wrong about this, but I think that, at file scope,

n = 0;

defines a static int object named "n" and initializes it to 0. If so,
then a similar definition at block scope would create the ambiguity I
mentioned. Or perhaps there were different rules for file scope and
block scope.
 
B

Ben Pfaff

Keith Thompson said:
I may still be wrong about this, but I think that, at file scope,

n = 0;

defines a static int object named "n" and initializes it to 0. If so,
then a similar definition at block scope would create the ambiguity I
mentioned. Or perhaps there were different rules for file scope and
block scope.

The syntax from the C90 draft I have here says:

translation-unit:
external-declaration
translation-unit external-declaration

external-declaration:
function-definition
declaration

declaration:
declaration-specifiers init-declarator-list<opt> ;

declaration-specifiers:
storage-class-specifier declaration-specifiers<opt>
type-specifier declaration-specifiers<opt>
type-qualifier declaration-specifiers<opt>

I don't see how declaration-specifiers can expand to an empty set
of terminals.
 
K

Keith Thompson

Ben Pfaff said:
Keith Thompson said:
I may still be wrong about this, but I think that, at file scope,

n = 0;

defines a static int object named "n" and initializes it to 0. If so,
then a similar definition at block scope would create the ambiguity I
mentioned. Or perhaps there were different rules for file scope and
block scope.

The syntax from the C90 draft I have here says: [snip]
I don't see how declaration-specifiers can expand to an empty set
of terminals.

I was referring to pre-ANSI C, not C90.
 
B

Ben Bacarisse

Keith Thompson said:
Ben Pfaff said:
Keith Thompson said:
I may still be wrong about this, but I think that, at file scope,

n = 0;

defines a static int object named "n" and initializes it to 0. If so,
then a similar definition at block scope would create the ambiguity I
mentioned. Or perhaps there were different rules for file scope and
block scope.

The syntax from the C90 draft I have here says: [snip]
I don't see how declaration-specifiers can expand to an empty set
of terminals.

I was referring to pre-ANSI C, not C90.

Yes, in very early C

n = 0;

is valid at file scope (not a term used in the early C manual I have)
but not in a function. At the top of a function, a definition must
have either a storage class or a type. Note "at the top of a
function" -- declarations and definitions are not permitted in other
blocks, only the block that makes up a function's body.
 
K

Keith Thompson

Ben Bacarisse said:
Yes, in very early C

n = 0;

is valid at file scope (not a term used in the early C manual I have)
but not in a function. At the top of a function, a definition must
have either a storage class or a type. Note "at the top of a
function" -- declarations and definitions are not permitted in other
blocks, only the block that makes up a function's body.

That's surprising, but I see you're right. The C manual from 6th
Edition Unix, May 1975,
<http://cm.bell-labs.com/cm/cs/who/dmr/cman.pdf>, has:

compound-statement:
{ statementlist }

statement-list:
statement
statement statementlist

and:

The function-statement is just a compound statement which may have
declarations at the start.

function-statement:
{ declaration-list[opt] statement-list }

I think C's ancestor, B, did allow declarations in nested blocks, and
K&R1 C (1978) certainly did.
 
P

Phil Carmody

Richard Heathfield said:
I will gladly provide a C test just for you. It's about on a par with
the test on which you just scored 100%, so you should have no
difficulty scoring 100% (i.e. ten marks) on this one, too.

I think 6 and 7 might need honing. (Oh, my, implicit int, surely no?)

Disappointed to see no valued stoned in the final question!

Phil
 
P

Phil Carmody

Keith Thompson said:
Tom St Denis said:
Maybe I don't get the question but UB means runtime behaviour not
compile time behaviour.

i = ++i;

May be UB, but it's syntactically valid and should compile to *A*
result [of unspecified behaviour]. So the following #error should
provoke a diagnostic you expect.

C99 3.4.3p2:

NOTE Possible undefined behavior ranges from ignoring the
situation completely with unpredictable results, to behaving
during translation or program execution in a documented manner
characteristic of the environment (with or without the issuance of
a diagnostic message), to terminating a translation or execution
(with the issuance of a diagnostic message).

However I don't believe an implementation is required to terminate
translation on seeing "i = ++i;" unless it can prove that the
statement will always be executed.

(I think that most or all implementations will honor the #error
directive even in the presence of inevitable undefined behavior,
but that wasn't the question.)


Do the processing phases disambiguate?

Phil
 
S

spinoza1111

Question 2: " In general (other than within string constants like "Hello
World" and a few obscure constructs), what effect does the amount of
whitespace (spaces and tabs) between code elements have on a C program's
compiled output?"

Hmm...

int x;
intx;

Apparently, whitespace is critical.  But it could be spaces or tabs.  But
neither "have meaning" in and of themselves.  I don't see a single viable
answer there.

Use your common sense. Zero whitespace is different.

The inability to read with commonsense started the Herb Schildt
nonsense.
Question 4: "How does one indicate that certain text is to be treated as
a "comment" in the classic C language?"

I don't know - what is "the classic C language"?  K&R?  C89?  C99?  Some
obscure dialect only supported by MSVC 1.3?

Use your common sense. There was a classic C same as there is an
English language. If we consider programming languages to be a type of
human language in which a "programming language" is actually (cf.
Knuth) a language for humans to communicate their intentions as to
using computers, then it's plain there was a classic C.

5. What will this piece (snippet) of C code print to the screen?
  printf("Hello World");

Since C doesn't define a screen - or require one - there's no expectation
that any output will be sent to "the screen", which may not exist at
all.  Further, there is neither an \n or an fflush(stdout) involved, so
there may not be any output *at all*.

Use your common sense and don't be a smart ass. This type of literal
hermeneutics destroys both charity and communication.
 6. Is there a difference between i++ and ++i ?

Absolutely, yes.  Which, oddly, isn't an option.

 9. In the C language, how does one write the statement, "if i NOT equal
to zero"?

 if ( ! i )  - which, again, isn't an option.

Maybe I'm missing something... were these supposed to be questions to
help one test one's C knowledge?  If so, why does the quiz offer so few
correct answers?

Use your common sense. What was your score?

Whatever happened to the very idea that programming ability was partly
or wholly expressed in the ability to understand and to explain?
 
S

spinoza1111

In

spinoza1111wrote:


I will gladly provide a C test just for you. It's about on a par with  

Asshole. A TEST is somthing which more than one person can take.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top