The ‘C’ test. Part – V

Data declarations
5. Using the variable a, give definitions for the following:
a) An integer
b) A pointer to an integer
c) A pointer to a pointer to an integer
d) An array of 10 integers
e) An array of 10 pointers to integers
f) A pointer to an array of 10 integers
g) A pointer to a function that takes an integer as an argument and returns an integer
h) An array of ten pointers to functions that take an integer argument and return an integer

The answers are:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer

People often claim that a couple of these are the sorts of thing that one looks up in textbooks-and I agree. While writing this article, I consulted textbooks to ensure the syntax was correct. However, I expect to be asked this question (or something close to it) when I’m being interviewed. Consequently, I make sure I know the answers, at least for the few hours of the interview. Candidates who don’t know all the answers (or at least most of them) are simply unprepared for the interview. If they can’t be prepared for the interview, what will they be prepared for

…to be continued  

The ‘C’ test. Part – IV

Infinite loops
4. Infinite loops often arise in embedded systems. How does you code an infinite loop in C?

There are several solutions to this question. My preferred solution is:

while(1)
{
ý
}

Many programmers seem to prefer:

for(;;)
{
ý
}

This construct puzzles me because the syntax doesn’t exactly spell out what’s going on. Thus, if a candidate gives this as a solution, I’ll use it as an opportunity to explore their rationale for doing so. If their answer is basically, “I was taught to do it this way and I haven’t thought about it since,” it tells me something (bad) about them.

A third solution is to use a goto :

Loop:

goto Loop;

Candidates who propose this are either assembly language programmers (which is probably good), or else they are closet BASIC/FORTRAN programmers looking to get into a new field.

…to be continued 

The ‘C’ test. Part – III

3. What is the purpose of the preprocessor directive #error?

Either you know the answer to this, or you don’t. If you don’t, see Reference 1. This question is useful for differentiating between normal folks and the nerds. Only the nerds actually read the appendices of C textbooks to find out about such things. Of course, if you aren’t looking for a nerd, the candidate better hope she doesn’t know the answer.

A preprocessor error directive causes the preprocessor to generate an error message and causes the compilation to fail.

A #error directive has the form:

_error.jpg

The argument preprocessor_token is not subject to macro expansion.

The #error directive is often used in the #else portion of a #if-#elif-#else construct, as a safety check during compilation. For example, #error directives in the source file can prevent code generation if a section of the program is reached that should be bypassed.

For example, the directive
#define BUFFER_SIZE 255
#if BUFFER_SIZE < 256
#error “BUFFER_SIZE is too small.”
#endif

generates the error message:
BUFFER_SIZE is too small.

Links: 

http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc09error.htm

http://www.la.utexas.edu/lab/software/devtool/gnu/cpp/cpp_40.html 

…to be continued 

The ‘C’ test. Part – II

2. Write the “standard” MIN c-that is, a macro that takes two arguments and returns the smaller of the two arguments.

#define MIN(A,B)
((A)
<
= (B) ? (A) : (B))

The purpose of this question is to test the following:

Basic knowledge of the #define directive as used in macros. This is important because until the inline operator becomes part of standard C, macros are the only portable way of generating inline code. Inline code is often necessary in embedded systems in order to achieve the required performance level

Knowledge of the ternary conditional operator. This operator exists in C because it allows the compiler to produce more optimal code than an if-then-else sequence. Given that performance is normally an issue in embedded systems, knowledge and use of this construct is important

Understanding of the need to very carefully Inline code

I also use this question to start a discussion on the side effects of macros, for example, what happens when you write code such as:

least = MIN(*p++, b);

…to be continued

The ‘C’ test. Part – I

An obligatory and significant part of the recruitment process for embedded systems programmers seems to be the “C test.”

From the interviewee’s perspective, you can learn a lot about the person who has written or administered the test. Is the test designed to show off the writer’s knowledge of the minutiae of the ANSI standard rather than to test practical know-how? Does it test ludicrous knowledge, such as the ASCII values of certain characters? Are the questions heavily slanted towards your knowledge of system calls and memory allocation strategies, indicating that the writer may spend his time programming computers instead of embedded systems? If any of these are true, then I know I would seriously doubt whether I want the job in question.

From the interviewer’s perspective, a test can reveal several things about the candidate. Primarily, you can determine the level of the candidate’s knowledge of C. However, it’s also interesting to see how the person responds to questions to which they don’t know the answers. Do they make intelligent choices backed up with good intuition, or do they just guess? Are they defensive when they are stumped, or do they exhibit a real curiosity about the problem and see it as an opportunity to learn something? I find this information as useful as their raw performance on the test.

With these ideas in mind, the ‘C ‘ test is heavily slanted towards the requirements of embedded systems. This is a lousy test to give to someone seeking a job writing compilers!
This test may be given to a wide range of candidates. Most entry-level applicants will do poorly on this test, while seasoned veterans should do very well. Points are not assigned to each question, as this tends to arbitrarily weight certain questions. However, if you choose to adapt this test for your own uses, feel free to assign scores.

This series of tests is divided in 10 parts. The first part starts today.

Preprocessor

Using the #define statement, how would you declare a manifest constant that returns the number of seconds in a year? Disregard leap years in your answer.

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

I’m looking for several things here:

  • Basic knowledge of the #define syntax (for example, no semi-colon at the end, the need to parenthesize, and so on)
  • An understanding that the pre-processor will evaluate constant expressions for you. Thus, it is clearer, and penalty-free, to spell out how you are calculating the number of seconds in a year, rather than actually doing the calculation yourself
  • A realization that the expression will overflow an integer argument on a 16-bit machine-hence the need for the L, telling the compiler to treat the variable as a Long
  • As a bonus, if you modified the expression with a UL (indicating unsigned long), then you are off to a great start. And remember, first impressions count!

…to be continued