Hmm!! no compilation/linker error!!! Why is it so??
November 15, 2014 3:53 PM   Subscribe

C puzzles - Dear visitor, Thanks for your interest in C programming. In this page, you will find a list of interesting C programming questions/puzzles. Not a huge list, but an interesting one.
posted by Wolfdog (28 comments total) 25 users marked this as a favorite
 
For this one: why it crashes on IA-64 and not x86...
int main()
{
      int* p;
      p = (int*)malloc(sizeof(int));
      *p = 10;
      return 0;
}
I'm going to guess that it's because he doesn't include stdlib.h, in C an undeclared function is defined to return int (instead of void* like we would expect), sizeof(int) is not large enough for a pointer on IA-64 (or amd64/x86_64).

But this is the prime reason I hate questions like these in interviews. The compiler immediately warns you about the implied declaration, and clang even tells you how to fix it. No decent programmer needs to know why this code crashes, because a decent programmer would fix the damn warning.
posted by sbutler at 4:28 PM on November 15, 2014 [9 favorites]


int main() { return 0; }

Optimized and debugged that for you.

(I hate questions like that too.)
posted by Foosnark at 4:36 PM on November 15, 2014 [11 favorites]


No decent programmer needs to know why this code crashes, because a decent programmer would fix the damn warning.

Some of these are tricky. The first relies on knowing that sizeof returns an unsigned integer type, which causes problems downstream. Enabling compilation warnings doesn't catch that.
posted by a lungful of dragon at 4:44 PM on November 15, 2014


These problems can be helpful in learning the language, but I agree they are not particularly useful in interviews.
posted by humanfont at 4:53 PM on November 15, 2014


*points excitedly*

DUFF'S DEVICE! DUFF'S DEVICE! I KNOW THAT ONE!

I actually have no idea why I know it. I have literally never used C for anything ever.

...I guess it struck me as obnoxious in an aesthetically pleasing way when I first read about it?

Anyway, apparently it's stuck with me.
posted by nebulawindphone at 5:16 PM on November 15, 2014 [3 favorites]


Going further, some of these are actually pretty decent interview questions, because like the sizeof question, they require more than a superficial knowledge of the language, and they force the asker to reveal understanding of the functions being used and how they actually work (and why code does not behave as expected, as a result).
posted by a lungful of dragon at 5:24 PM on November 15, 2014


These are some fun little problems. True, compilers will tell you about many of the errors; but after seeing the same error message a few times you should learn not to make that mistake in the first place. Details like sizeof(int) vs. sizeof(int*), printf() output not appearing until the buffer is flushed by a "\n", and floating-point .1+.1+.1!=.3 are common errors that it's useful to know about.

On the other hand, some of these problems are kind of cheating. One of them has a syntax error with defa1ut instead of default, but nevertheless the syntax highlighting shows it as a keyword. No IDE would do that. Same goes for the one which tries to define void OS_HP-UX_print().
posted by Rangi at 6:40 PM on November 15, 2014


One of them has a syntax error with defa1ut instead of default, but nevertheless the syntax highlighting shows it as a keyword. No IDE would do that.

I thought the same thing, but then it turns out the syntax highlighting in my vim will highlight anything before the colon in a switch-case, it seems.

But I agree with the general point: the puzzles could use a little more care to make sure there aren't unintentional typos or whatever which distract from the intended lesson for each one. For example, one of the puzzles is missing an #include at the top, but that's not the aim of the puzzle.
posted by theyexpectresults at 7:34 PM on November 15, 2014 [1 favorite]


I went to a JavaOne session for one of Bloch's books in this vein. It definitely reminded me that I am only a simple country language lawyer. I'd look at the examples, and say: there's not a got-damn thing wrong with that code, but it was not so, and Bloch would reveal what perils lied within.
posted by thelonius at 7:41 PM on November 15, 2014


I did an interview with Citrix back in the 90s that was all bullshit like this done live in front of a whole panel of those assholes.
posted by w0mbat at 8:31 PM on November 15, 2014 [2 favorites]


Oh for God's sake: like anyone's ever had to use Duff's Device since the 1980s. Like anyone's ever needed to know Duff's Device since the 1980s.

I'm with sbutler: these are crappy questions in isolation because they're contextless. What warnings do they produce on compilations? What if I add -Wall -Wextra? (And why isn't the Makefile already setting those by default?) What symptoms do they crash with? What state will I find when I breakpoint within it?

The key to these sort of things is usually less an "ah, I know exactly what this is" and more general "oh, signed/unsigned integer promotions are always a bit tricky" or "so where's the prototype for this function then?" gut-feel. Simply knowing where the minefields are in C is 90% of the battle: because that tells you where to focus your attention.

(Also, the separation between those who always implicitly trust their own code vs those who always verify it. I think it was Writing Solid Code that was gung-ho on "always single-step it to make sure it's behaving how you think it should be behaving"; and almost always when I do I either gain good confidence or expose some obvious problem.)

(And yes, those should be unit tests; but goddamn, it's hard in huge-system SHIP-IT-NOW projects to carve out time to do proper low-level unit tests. And that's a whole better interview question to ask: not "what's wrong with this code" but "how would you test this code for correctness"?)
posted by We had a deal, Kyle at 8:40 PM on November 15, 2014 [2 favorites]


(And yes, those should be unit tests; but goddamn, it's hard in huge-system SHIP-IT-NOW projects to carve out time to do proper low-level unit tests. And that's a whole better interview question to ask: not "what's wrong with this code" but "how would you test this code for correctness"?)

I haven't interviewed anyone in years (my current employer doesn't let me near candidates, for fear that I'd scare them off), but when I did I used to print out a man page for qsort() and tell the candidate to tell me how to test it. As it turned out, the question was outstandingly effective. Most of the candidates couldn't even invoke qsort, let alone successfully reason about testing the algorithm.
posted by doomsey at 8:48 PM on November 15, 2014 [1 favorite]


my current employer doesn't let me near candidates, for fear that I'd scare them off

I keep trying to do this; hasn't worked yet.

(I tend to be "so let me tell you what it's *really* like working here" as an interviewer; it's what I'd want to hear from the other side of the table. And if a candidate accepts an offer, I'd rather it be with eyes fully open to what they're walking into.)
posted by We had a deal, Kyle at 9:29 PM on November 15, 2014 [2 favorites]


No decent programmer needs to know why this code crashes, because a decent programmer would fix the damn warning.

I agree that they would....but every software company I've worked at has at least one unofficial Bugfinder General. Even the decent programmers will call on them when a strange and deadly bug rears its head. They, usually, know all of this stuff, and more. They might not make those mistakes themselves, but can find them when required.

I don't think interviewing for this sort of thing in a live situation is always the best way to find hires, but certainly "tell me about the worst bug you ever found" and "tell me about the worst bug you ever wrote" are questions a programmer worth their salt should relish answering,
posted by Jon Mitchell at 9:54 PM on November 15, 2014 [1 favorite]


There are only two things to remember when debugging C code:

1. C hates you
2. Alcohol does not help
3. SEGFAULT
posted by fallingbadgers at 11:11 PM on November 15, 2014 [11 favorites]


1. C hates you
2. Alcohol does not help
3. SEGFAULT


Too easy - you started with a 1. Should be:

0. C hates you
1. Alcohol does not help
2. inscrutable memory leak
posted by A Thousand Baited Hooks at 12:26 AM on November 16, 2014 [10 favorites]


while a lot of the items were uninteresting duds, I'm still looking for the other two ways to make the "-"-printing loop work right...
posted by jepler at 6:09 AM on November 16, 2014


0. Bug occurs here
1. C hates you
2. Alcohol does not help
3. SEGFAULT

7. Exploit goes here
posted by eriko at 8:25 AM on November 16, 2014 [1 favorite]


Now I feel foolish.
The very last problem is likely solved trivially but I have absolutely no idea how this is accomplished. (Write Hello World program without using any semi-colons). Before I begin to googleate this, anyone here having trouble with this/already know what the deal is?
posted by Golem XIV at 10:06 AM on November 16, 2014


Write Hello World program without using any semi-colons

Wasn't there some ANSI brain-damage back in the day about how certain machines couldn't handle certain (really common) special characters, so an ANSI-compliant compiler was required to accept monstrosities like %%SEMICOLON%% or \\OPEN_CURLY instead of ';' and '{'? I couldn't find it on a quick search, but I know there was something like that...

Not sure why it would be a useful interview question, except to see how long somebody has been around and whether they were competent enough at the basics to have time to look at and remember the weird stupidities, but anyway...

Most enjoyable interview I ever had was at VMware, where the tech guys wanted me to tell them exactly how Hello World managed to display characters on the screen. Starting from the power cord.
posted by spacewrench at 10:17 AM on November 16, 2014 [1 favorite]


My personal answer was: #error Hello World
I don't think there are any digraphs or trigraphs for semicolon, but I didn't check.
posted by jepler at 10:23 AM on November 16, 2014 [1 favorite]


aha there are some real answers (compiler invocation produces an executable, running the executable prints the string). Hint: {}
posted by jepler at 10:26 AM on November 16, 2014 [1 favorite]


At first I was thinking it could be done with some comma list evaluation trickery (and maybe it can be) but really all it came down to for me was the fact that I had never known that you can skip explicitly returning a value from main(). (And that doesn't even generate a warning??? yeesh)
posted by Golem XIV at 10:45 AM on November 16, 2014


It is undefined behavior for main to reach the end without returning a value, because main's return value is used to define the exit status of the program.
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined. (source: c99 draft standard, 6.9.1.12)
However, you can call exit() directly to avoid this problem.
posted by jepler at 11:31 AM on November 16, 2014


The "print a minus sign 20 times" problem is a fun one. I found one solution myself and then googled the two others from stackoverflow.com. All of them are of course horrible coding style, but the third one is just the right kind of combination of "wow, that's it!" and "push that code into the repository and I will punch you in the face".
posted by ikalliom at 1:13 PM on November 16, 2014


jepler, I hate to be that guy*, but please see section 5.1.2.2.3: "Hosted Environment: Program Termination":
If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.
Also somewhat relevant is 7.20.4.3.5, "Communication with the environment: the exit() function":
If the value of status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned.
*: I actually really like being that guy.
posted by autopilot at 8:19 PM on November 16, 2014 [1 favorite]


If they asked me to code C with no semicolons at an interview, I'd be inclined to tell them that, if semicolons stop working one day, I would just go home.
posted by thelonius at 4:09 AM on November 17, 2014 [1 favorite]


OK, I stand corrected about the special return value of main. Apparently this is a C89 vs C99 difference, or at least the version of gcc I have at hand only treats the "reaching the } that terminates main" specially when I specify -std=c99. However, since I was quoting the c99 standard already, I do clearly lose one beard point.
posted by jepler at 8:14 PM on November 17, 2014


« Older A stop for sandwiches at the Crown Hotel then off....   |   "I tried to stay with things until I thought they... Newer »


This thread has been archived and is closed to new comments