dspfun said:
Are suffixes allowed on expressions?
No (unless the expression happens to be an integer constant).
For example, is the following allowed:
#define SECONDS_PER_YEAR (60 * 60 * 365) UL
Nope.
I found this in a C test at
http://www.embedded.com/2000/0005/0005feat2.htm , however, I am not
able to compile when using this macro (or just the expression "a =
(60 * 60 * 365) UL;").
Where in the standard does it say that it is allowed/not allowed?
Suffixes such as UL are described in C99 6.4.4.1, "Integer constants"
(and similar suffixes are described in 6.4.4.2, "Floating constants").
The fact that they aren't described anywhere else, particularly the
fact that the grammar permits them only in those contexts, implies
that they aren't permitted anywhere else. (There's no need to state
that they're not allowed.)
It would also be interesting to hear if there are any faults in the
other questions and answers in the test.
Some of the code layout is messed up, at least in my browser. In some
cases, lines are split before and after '<' characters. I'd guess
this isn't the author's fault.
As you say, he completely messed up on the first question. Failing to
compile code to be used in a published article is a *big* mistake.
In question 8 about the volatile keyword, he says that the variable
can be changed unexpectedly, but he fails to mention that when the
*program* changes a volatile variable, the new value must actually be
stored rather than cached. He covers the implications for reading the
variable, but not for writing it. (The latter is a constraint on the
implementation, not on the programmer, so perhaps that's excusable.)
In question 14, he needlessly casts the result of malloc(). Worse
than that, he's mistaken about the actual point of the question, the
result of malloc(0). He says, or strongly implies, that malloc(0)
always returns a valid (non-null) pointer. In fact, it's
implementation-defined whether malloc(0) returns a null pointer or a
unique non-null pointer.
Question 15 asks which of these is preferred:
#define dPS struct s *
typedef struct s * tPS;
as a way to define an alias for a pointer to type "struct s". Apart
from failing to mention the inadvisability of aliasing a pointer type,
he gets the asnwer right, but his attitude here is odd to the point
of being wrong:
This is a very subtle question, and anyone who gets it right (for
the right reason) is to be congratulated or condemned ("get a
life" springs to mind).
The problem, of course, is with declarations like:
dPS p1, p2;
tPS p3, p4;
But this isn't a remarkably obscure point, as he implies; it's
something that every C programmer should know.
There's a contact address in the article; I'll send him pointers to
your article and my followup.