I put this up on Ben's Irregular a while back, but I never had time to go back and actually take the test myself until now.http://www.embedded.com/2000/0005/0005feat2.htm
A couple of notes...Questions 1 and 2
: Really excellent points here. Casting to long for the answer to the year worth of seconds constant is particularly insightful. And you wouldn't believe the weird-ass, untraceable bugs that come about due to weird order of ops in macros. Parenthesize ALWAYS!Question 3
: I actually didn't know this one off the top of my head. I was pretty sure it caused the preprocessor to throw an error, but didn't know the exacts.Question 4
: There are a lot of correct answers to this one. You could also use a do/while. I personally like "#define
FOREVER 1 while(FOREVER)". It's a little more obfuscated if you try and puzzle it out, but on a quick scan of the code I think it's actually more readable and the intent is clearer.Q 5
: I couldn't get the last one. Pointers to functions I can do fine, but throw that array in there and I'm history...Q 6
: I knew all three uses of static, AND I've used both of the last two in production code. (Oddly, I can't remember ever using "static" in the sense of making a variable that keeps its value between function calls!)Q 7: As soon as the interviewee says "const means constant," I know I'm dealing with an amateur.
Uh, not really. I do indeed like the definition of "const" as "read-only" but even that fails somewhat later on when he gets to talking about volatiles. Const just means const - it has its own conditions and semantics.Q 8:
Up to the "additional questions" part of this, I'm fine with it. But then he goes and does something really, REALLY dumb that betrays a lack of understanding of how C passes parameters to functions.
Remember how C makes a copy of variables passed to functions? Remember that from C 101? Por exemplo:
n = 3;
i = i + 1;
Okay now, the $64k question: What is the value of main()'s variable "n" after someFunc() has been called?
The answer is: "n is unchanged. It remains 3."
Now, why? Because, the compiler passes a copy
of each parameter to the function, not the actual param itself. Which means changes you make inside the function don't effect the outside variable. Hence all the silly contortions C programmers have to go through with passing and returning pointers, etc.
The author goes through a completely unnecessary series of steps here to do what the compiler will do for him automatically. And if you let the compiler do it, it will make more intuitive sense, and be easier to read and maintain to boot.
The author fails this question, although he wrote it himself, for not understanding what the compiler is doing behind his back. In embedded systems, you need to always understand what the compiler is doing behind your back. (This is even more crucial if you write C++ for embedded.)
The only reason I can think of to ever do it his way is if you have to wait for a certain moment in the computer's internal state before doing the math on the volatile variable. In that case, it would make sense to encapsulate the waiting and the calculation inside the function. But for normal cases...Q 14:
This is an utterly excellent question, and tests if you've really, really slogged through the nasty, evil guts of compilers (or at least the K&R book
) and really truly understand deep down how the arena and memory allocation
works in most all C compilers.Q 16:
I'm not actually sure if this defaults to pre-increment b or post-increment a. The point of the question is excellent, though: Don't do this! You're not saving yourself anything, and you're probably going to cause the person who maintains your code a big headache. Yes Virginia, good style can be important!