Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Consider the following exam / interview question:


Implement the strcpy() function in C: void strcpy(char *destination, char *source);

The strcpy function copies the C string pointed by source into the array pointed by destination, including the terminating null character. Assume that the size of the array pointed by destination is long enough to contain the same C string as source, and does not overlap in memory with source.


Say you were the interviewer \ examiner, how would you grade the following answers to this question?

1)

void strcpy(char *destination, char *source)
{
  while (*source != '\0')
    {
      *destination = *source;
       source++;
       destination++;
    }
    *destination = *source;
}

2)

void strcpy(char *destination, char *source)
    {
       while (*(destination++) = *(source++)) ;
    }

The first implementation is straightforward - it is readable and programmer-friendly.

The second implementation is shorter (one line of code) but less programmer-friendly; it's not so easy to understand the way this code is working, and if you're not familiar with the priorities in this code then it's a problem.

I'm wondering if the first answer would show more complexity and more advanced thinking, in the interviewer's \ examiner's eyes, even though both algorithms behave the same, and although code readability is considered to be more important than code compactness. It seems to me that since making an algorithm this compact is more difficult to implement, it will show a higher level of thinking as an answer in an exam. However, it is also possible that an interviewer \ examiner would consider the second answer not good because it's not readable.

I would also like to mention that this is not specific to this example, but general for code readability vs. compactness when implementing an algorithm, specifically in exams \ interviews.

share|improve this question
1  
One advantage of the concise one is that it has less chances of having typos in those long variable names, and thus more chances of compiling (: –  Mat Sep 2 '12 at 15:27
    
Good luck with unterminated input strings. :) –  lynxlynxlynx Sep 2 '12 at 16:24
1  
I actually find the second version more friendly. In the first one you have duplicate code and it is just much more to read. –  Felix Dombek Sep 2 '12 at 17:39
1  
Do not give the first answer in a programming interview for a position in C: they might think you're some Java programmer. The second answer clearly shows that you are no Java programmer at all, but a Real Programmer who has read The Book. –  dasblinkenlight Sep 2 '12 at 19:49
    
What "priorities" to be familiar with? –  Christian Rau Sep 4 '12 at 11:20
show 2 more comments

8 Answers 8

up vote 8 down vote accepted

The second answer shows the developer understands the C edge cases better. However, the first version is easier to read and understand because it does not require understanding of these edge cases.

If you are asked the question, ask the interviewer or examiner what they are looking for. If in doubt, go for readable code over compactness every time. Interviewers and examiners can reach decision fatigue quickly and making it easier on them will help you.

If the interviewer or examiner wants more, do the readable version first then given them the second version and explain why it works. This will also help you because you can make shorter conceptual leaps.

share|improve this answer
1  
+1. If you are the interviewer, you are looking for a candidate who understands and can produce both idioms, but knows that some programmers have difficulty with the ultra-concise answer. Personally I would prefer a candidate who mentions buffer overruns and security when discussing strcpy. This may depend on environment –  MarkJ Sep 3 '12 at 17:40
add comment

It all depends on the requirements for that piece of code.

  • Is it meant to be fast?
  • Is it meant to use minimal memory?
  • Is it meant to be reliable?
  • It it meant to be maintainable?

The other thing you need to consider is the guideline:

Make it right, then make it fast

The first example would be the ideal first implementation of the function which would satisfy the 3rd and 4th requirements on my list above. It would also be sufficient for an application that wasn't time critical or memory limited etc. The second example might be what you would code if you needed to satisfy the 1st and 2nd requirements or you later discovered issues with your initial code (unlikely in this specific case).

As far as a tester is concerned the actual complementation shouldn't be a factor in determining whether the code passes the tests or not. All that matters is that it:

  1. Produces the correct result
  2. Does so in a "reasonable" time (which will vary from application to application)
  3. Uses a "reasonable" amount of computer resources (ditto)

However, on re-reading your question I see that you are using the word "tester" for the person conducting the interview. In this case as you are looking at the code to judge the skill level or competency of the programmer, then the second example would be "better" as it shows that the programmer understands how pointers and pointer incrementation works.

The caveat to that though is unless the code is truly "write once" (i.e. it's never going to be looked at again) you'd want the code in the first example.

share|improve this answer
2  
In general I agree, though with this example(yeah, I know this case was just an example but anyway) I'd argue that both blocks of code compile to the exactly equivalent performing machine code, if not the exact same machine code in fact. There is no obvious reason why there would be performance penalty in the former piece of code after compilation. –  zxcdw Sep 2 '12 at 15:46
1  
Shouldn't both versions be identical as far as performance and memory use are concerned? Remember, we're talking about different ways to implement the same algorithm. –  delnan Sep 2 '12 at 15:47
    
@delnan - There might be variations with different compiler's optimisation strategies. –  ChrisF Sep 2 '12 at 15:58
    
@zxcdw - you might be a the mercy of the compiler/optimiser here though. Sorry for missing that - it's been a while since I did c :) –  ChrisF Sep 2 '12 at 15:59
1  
@delnan To clarify an irrelevant point, typically such a loop is implemented in some less than 20 bytes of x86 assembly. Two movs, two incs and a test and conditional jump. Function overhead is some ten or so bytes if not inlined. Some 20 bytes to filesize overhead if not inlined. Whether that is one or ten bytes smaller/bigger than some other implementation is irrelevant from performance perspective. And as mentioned, C implementation which behaves equivalently also gets implemented equivalently in machine code. –  zxcdw Sep 2 '12 at 17:00
show 2 more comments

In C the expression x++=y++ is extremely common and thus easily understood, and IMO should be preferred over the longer x=y; x++; y++; whenever possible as it expresses the INTENT better. That leaves the check for terminating the loop.

while(*source != '\0')

vs

while(*source)

vs

while(*destination++ = *source++){}

Understanding the 2nd and 3rd depends upon understanding two things, that C considers zero to be false and everything non-zero to be true and that the assignment operators return a result.

Both of these should be ingrained in even a junior C programmer and easily picked up by those coming from another language.

In short, I don't consider the second harder to read, and in fact find the first more difficult to read in the context of a C program -- in a language without ++ the first would of course be required, but programming in langauge a as if it was language b is confusing. The question "why is this code doing that" is much harder than "what is this code doing", and non-standard usage makes me ask why...

Now, if you want to mark these down for some reason, look no further than the lack of comments. When dealing with pointers, such unstated restrictions are just begging for mistakes.

share|improve this answer
add comment

In general, if I'm asking people to write code in an interview, I'm looking to see if they write code that I'd want to debug and maintain. That would lead me to prefer answers like the first example.

However, anyone asking this specific question is probably testing to see if the interviewee knows the very common strcpy idiom in the second example. This is a test of their knowledge of pointers and C, not of the readability or compactness of their code.

share|improve this answer
add comment

There are a few things which come to mind.

If it works, it should be good enough. Focusing obsessively on code formatting isn't any more productive as focusing obsessively on premature optimization. In most cases it adds no value.

You mentioned "it's not so easy to understand the way this code is working, and if you're not familiar with the priorities in this code then it's a problem.". That is then a problem because the programmer isn't competent enough with such structures. Such compact structures are actually quite common in simple pieces of code like that, and any experienced programmer immediately understands and actually prefers them because they are simple.

This is highly a matter of style, which varies between persons. I don't think there's a correct answer to question like this.

share|improve this answer
add comment

Tester context

First, let us define testers. The distinction between software development and software testing roles happens to involve source code access. Developers are constantly in touch with details of the code, focusing on unit testing. Team members called testers are nearly always intentionally oblivious of the lowest levels of implementation, focusing on integration testing, stress testing, load testing, compatibility testing. A tester is therefore most likely to notice source code structure when a typo breaks a build or when a stack trace makes it to the logs.

Using whatever style that other members of your team find easy to maintain usually means that testers will see fewer build breaks and behavior deficiencies in the long run. When in doubt, ask your team or go after simplicity.

Code review context

When code is being reviewed by a fellow developer prior to commit, differences in code style do matter, of course. The one that is standard within the organization/product/project, or otherwise familiar to other team members, is the correct one. The others are incorrect - minus points and rework.

If a developer can explain why a particular practice is in their view better than the current standard, and why the standard should be updated (this question already provides a plenty of available arguments either way), that is plus points, but there is no reason for intentionally deviating first and explaining only second.

Interview context

During an interview, typos, indentation differences, etc., do not really matter. Your two implementations compile to the exact same binary code. Compared to the standard (pun intended) implementations of the same task, either of our equivalent samples is much easier to read, much slower, and also much safer to use to people not deeply familiar with the standard C library. This is partly because the "does not overlap" part of the task might have been translated to the restrict keyword but wasn't.

The difference in coding style does say things about the soul of the developer. Both coding styles shown are completely industry standard ones, so it would be silly to judge the experience or skills of the candidate based on coding style alone. However, it is possible that the two programmers would eventually be offered differently oriented roles, or that a particular organization would find a fit with only one of those two personality styles.

share|improve this answer
add comment

Why can't you give both answers?

I once had someone tell me I had the wrong answer in an interview and deny me the job because of it, even though my procedure worked. He wanted the quick way instead of the readable way (it was a game company). He explained his clever shortcut, but it was still a big disappointment for me. I sulked around feeling cheated for a couple weeks before looking up and trying out his solution. It turned out to have a serious bug that would have prevented it from working!

In hindsight, I should have continued working on the problem immediately after leaving the interview (or at least the next day when I cooled off). That way I could have contacted him and continued the discussion about the problem, maybe emailed him a test case to demonstrate where his preferred solution failed, and suggested a correction that solved the problem closer to his way, but without the bug.

Most of the candidates I've asked questions of in interviews have gotten them wrong. I finally gave up and just asked candidates to describe a recent project they felt excited about. That's probably a better interview question any way. Because it's open-ended, you get a feel for someone's style and perspective as well as their knowledge and ability. If anyone had ever given me two correct answers to a question and discussed the relative strengths and weaknesses, I think I would have passed out. Someone like that would have to be a convicted serial killer AND a sex offender to not get the job! Maybe I wasn't hiring from the best talent pool, but there you have it.

share|improve this answer
add comment

The first implementation is straightforward - it is readable and programmer-friendly.

The second implementation is shorter (one line of code) but less programmer-friendly; it's not so easy to understand the way this code is working, and if you're not familiar with the priorities in this code then it's a problem.

You have your answer there.

When interviewers look at your code, they will also see your coding style. Readability is important for production code, so try to show them you can write such code.
For an exam you should aim for understandability as well, so your code is not wrongfully determined to be faulty.

share|improve this answer
    
But when answering an exam / interview question, readability might be less important, because the code is not going to be looked at again. It's still important to make sure the interviewer will understand the code, but in my example the shorter code should be readable to anyone who knows how C pointers work. –  amiregelz Sep 3 '12 at 17:40
    
@amiregelz updated my answer with my view. –  Matsemann Sep 3 '12 at 18:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.