7

Why is still C99 mixed declarations and code not used in open source C projects like the Linux kernel or GNOME?

I really like mixed declarations and code since it makes the code more readable and prevents hard to see bugs by restricting the scope of the variables to the narrowest possible. This is recommended by Google for C++.

For example, Linux requires at least GCC 3.2 and GCC 3.1 has support for C99 mixed declarations and code

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
Eduardo
  • 2,327
  • 5
  • 26
  • 43
  • 7
    I really *dislike* mixed declarations because they make the code less readable and cause hard to see bugs. – Carl Norum Jun 11 '10 at 22:16
  • 1
    Justin, I couldn't disagree more with your edit. I *hate* seeing a title (in a large, bold font) that could apply to many languages, and having to look somewhere else on the screen for tags written in a low-contrast, small font in order to know if I have something to say about the question. Ambiguous titles that are disambiguated only by the tags are a usability nightmare. And on the subject of usability, tags usually add information, rather than displacing it. – Pascal Cuoq Jun 11 '10 at 22:21
  • 4
    @Carl, @Eduardo I think you're both overstating the possible bugs caused by the other's preferred style. Function scoped variables lead to code rot as code is removed and the variables become unused, whereas block scoping could lead to variable shadowing if one isn't careful about naming. Both problems are caught by a good set of compiler warnings, but narrow scoping remains superior because it makes it much easier to spot daft data usage patterns... which in turn leads to better, more understandable code. – Dan Olson Jun 12 '10 at 04:10
  • 1
    @Carl: I think that's a generalization: sometimes, mixed declarations can make code *more* readable; an example that often comes up: checking preconditions for function arguments first within the function body, because, you know - it's a *pre*-condition; adding another block (resulting in an additional level of indentation) just for that seems overkill, imo – Christoph Jun 12 '10 at 11:28
  • @Christoph, @Dan, sure there are always exceptions to a rule. I was really trying to state an opposing viewpoint in a humorous way more than really trying to make a unilateral argument about variable declarations. – Carl Norum Jun 12 '10 at 15:57
  • @Eduardo, ANSI C89-conforming declarations **do not** prevent narrowing the scope of variables at all, they only prevent mixing declarations with statements. It'd only take a few hours of practical experimentation with `gcc -std=c89 -pedantic` to discover this. Why not try that first before opining about code readability based on something you clearly do not understand? –  Dec 26 '13 at 21:41
  • Similar question: https://stackoverflow.com/questions/288441/variable-declaration-placement-in-c/4105334 – MarcH Jul 11 '21 at 02:15

7 Answers7

4

You don't need mixed declaration and code to limit scope. You can do:

{
  int c;
  c = 1;
  {
    int d = c + 1;
  }
}

in C89. As for why these projects haven't used mixed declarations (assuming this is true), it's most likely a case of "If it ain't broke don't fix it."

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
3

This is an old question but I'm going to suggest that inertia is the reason that most of these projects still use ANSI C declarations rules.

However there are a number of other possibilities, ranging from valid to ridiculous:

  • Portability. Many open source projects work under the assumption that pedantic ANSI C is the most portable way to write software.

  • Age. Many of these projects predate the C99 spec and the authors may prefer a consistent coding style.

  • Ignorance. The programmers submitting predate C99 and are unaware of the benefits of mixed declarations and code. (Alternate interpretation: Developers are fully aware of the potential tradeoffs and decide that mixed declarations and statements are not worth the effort. I highly disagree, but it's rare that two programmers will agree on anything.)

  • FUD. Programmers view mixed declarations and code as a "C++ism" and dislike it for that reason.

Dan Olson
  • 22,849
  • 4
  • 42
  • 56
2

There is little reason to rewrite the Linux kernel to make cosmetic changes that offer no performance gains.

If the code base is working, so why change it for cosmetic reasons?

Alan
  • 45,915
  • 17
  • 113
  • 134
  • 1
    There is no need to rewrite anything. But maybe narrowing variable scope in new code should be recommended. – Eduardo Jun 11 '10 at 23:06
  • There's something to be said for consistency across the code base. – Alan Jun 11 '10 at 23:54
  • 1
    It is after all the hobgoblin of small minds (a foolish consistency, that is). And nobody's mind is ever smaller than when they're considering coding standards ;-) – Steve Jessop Jun 12 '10 at 02:00
  • @Eduardo I haven't read the whole Linux src, but I also wrote in ANSI C. In my code my functions are small, and the variable scope can't be more narrow. For me this feature solve a problem which I have never met. – user26742873 Aug 26 '21 at 03:07
1

I don't remember any interdictions against this in the style guide for kernel code. However, it does say that functions should be as small as possible, and only do one thing. This would explain why a mixture of declarations and code is rare.

In a small function, declaring variables at the start of scope acts as a sort of Introit, telling you something about what's coming soon after. In this case the movement of the variable declaration is so limited that it would likely either have no effect, or serve to hide some information about the functionality by pushing the barker into the crowd, so to speak. There is a reason that the arrival of a king was declared before he entered a room.

OTOH, a function which must mix variables and code to be readable is probably too big. This is one of the signs (along with too-nested blocks, inline comments and other things) that some sections of a function need to be abstracted into separate functions (and declared static, so the optimizer can inline them).

Another reason to keep declarations at the beginning of the functions: should you need to reorder the execution of statements in the code, you may move a variable out of its scope without realizing it, since the scope of a variable declared in the middle of code is not evident in the indentation (unless you use a block to show the scope). This is easily fixed, so it's just an annoyance, but new code often undergoes this kind of transformation, and annoyance can be cumulative.

And another reason: you might be tempted to declare a variable to take the error return code from a function, like so:

void_func();
int ret = func_may_fail();
if (ret) { handle_fail(ret) }

Perfectly reasonable thing to do. But:

void_func();
int ret = func_may_fail();
if (ret) { handle_fail(ret) }
....
int ret = another_func_may_fail();
if (ret) { handle_other_fail(ret); }

Ooops! ret is defined twice. "So? Remove the second declaration." you say. But this makes the code asymmetric, and you end up with more refactoring limitations.

Of course, I mix declarations and code myself; no reason to be dogmatic about it (or else your karma may run over your dogma :-). But you should know what the concomitant problems are.

Tim Schaeffer
  • 2,616
  • 1
  • 16
  • 20
1

There is no benefit. Declaring all variables at the beginning of the function (pascal like) is much more clear, in C89 you can also declare variables at the beginning of each scope (inside loops example) which is both practical and concise.

arthurprs
  • 4,457
  • 3
  • 26
  • 28
0

Maybe it's not needed, maybe the separation is good? I do it in C++, which has this feature as well.

elcuco
  • 8,948
  • 9
  • 47
  • 69
0

There is no reason to change the code away like this, and C99 is still not widely supported by compilers. It is mostly about portability.

alternative
  • 12,703
  • 5
  • 41
  • 41
  • 3
    "C99 is still not widely supported by compilers" - is this a concern in the linux kernel? For example, would linux+gcc be bootstrapped using a C89 compiler for some platforms? – Steve Jessop Jun 12 '10 at 02:02
  • Possibly not for the Linux Kernel, since it is rather tied to GCC and its assembler, but for many projects it is a requirement. Linux is just too big to refactor all the code so that it does it like this for useless reasons. – alternative Jun 12 '10 at 11:28