7 ms·
Linux kernel coding style
- calafrax 9y ago> if you need more than 3 levels of indentation, you’re screwed anyway, and should fix your program. I hope some JS programmers read this
- paraknight 9y agoasync/await to the rescue!
- z3t4 9y agofunctions and closures to the rescue
- calafrax 9y agoThe first professor who I took a programming class from told us that anytime we needed to indent something we should be asking ourselves if we needed to create a new function and most times the answer would be yes. It was good advice.
- wvenable 9y agoIf your function is only called once it's better to leave it indented than to create a function.
- mklim 9y agoDepends on the context/language I think. Splitting a block of code into a function gives it a greppable name that (ideally) succinctly describes the point of the block. You can have that block just headed by a comment inline to try and do the same thing, but comments are extremely prone to getting ignored and left to grow outdated when the purpose of the code around them changes. It's easier for the reader to just mentally abstract away that block if it's separated into a function. And if that block is worth testing, it's much easier to do when it's isolated into its own function. There's reasons to keep the block inline too--like if you're working in a more resource constrained environment, or if the block isn't really isolated/self-contained enough to cleanly abstract away, or if the block in question isn't really doing anything substantial. But I wouldn't say that you should only abstract away code into functions to save yourself from literally copy/pasting the lines in multiple places.
- ams6110 9y agoYou could argue that it's better to make the function; the compiler will probably inline it if it's only used once, and it helps avoid having the logic duplicated if it's needed again (or by lazy copy/paste programmers).
- wvenable 9y agoMy point is not performance but that a function used only once is likely just contributing to one conceptual block of code. But now it's artificially divided up and one has to jump around to understand that code as a whole. There are exceptions of course but blindly adding functions to avoid indenting is probably going to lead to a harder to follow solution.
- z3t4 9y agoin js you can just leave the named function inline. i sometimes create functions that call themself so that i can just move it out if the code needs to be repeated, and i dont have to clutter the scope with more variables. with es6 js got bracket scoping, but i still prefer function scope and closures.
- dguo 9y agoI referenced this quote when my team was bikeshedding over our linting configuration, and I was pushing for a lower line limit.
- GhostVII 9y agoI think it is a bad idea to apply that rule to all programming languages though. If you are doing Java, for example, and have a function inside of a class, and a loop in the function, putting a condition inside of the loop would violate the rule, and that is a pretty common thing to do.
- arghwhat 9y agoConsider it from a base level rather than indent 0, and it will work for Java. The kernel guideline doesn't mention this due to being C specific. C++ can exhibit similar issues.
- arghwhat 9y agoEarly returns ftw (if (!cond) return; instead of if(cond) do();)!
- nerdponx 9y agoWhy are anonymous functions so popular in JS? Why not just name the callback?
- quotemstr 9y agoBecause Java is a kingdom of nouns, and for the most part (method handles, which are just fancy reflection objects, aside), you can't name a function without creating a closure. Anonymous callback: Foo.foo(() -> bar()); Named callback: private final class MyFooDelegate implements FooDelegate { @Override public void doFoo() { bar(); } } ... Foo.foo(new MyFooDelegate())
- pjmlp 9y agoYou forgotten about method handles.
- deleted 9y ago[deleted]
- dingo_bat 9y agoWhy name it if the name will never be used?
- wereHamster 9y agoThe name shows up in the stack trace, and you'll have a much better idea which path the code hit when it crashed.
- z3t4 9y agonaming things are hard and some programmers are willing to sacrifice their left hand if it means they can write shorter syntax.
- z3t4 9y agoseveral indentations in js is most of the time linear async flow, while in other languages it usually means branching complexity. while an experienced js programmer can deal with async code and avoid the so called callback hell, nesting the callback doesnt make it any harder to understand, just harder to test, debug and refactor.
- dimman 9y agoI think these guidelines are something every C programmer should atleast have read and reflected about. I've been coding according to these guidelines for quite a while with some minor modifications: Always use curly braces (especially when you're not alone coding in the codebase as it allows for easy modification without code ending up out of the intented scope). 80 char width; well I don't follow this one as I really do prefer long lines over broken lines for readability. Other than that I think these guidelines are great and offer consistency and easy to read code, in my opinion.
- nerdponx 9y ago80 char width helps encourage you to "do less stuff in each line", rather than "break lines at 80 chars". But I agree, after a few levels of indentation (which is sometimes unavoidable) you end up struggling.
- dingo_bat 9y agoAlso, when a function takes five arguments, and each_argument_looks_like_this, it's easy to hit 80 chars!
- _asummers 9y agoDepending on the verbosity of the name, even a no arg function might exceed 80+ chars. We have a few instances of test convenience functions in our non-C code base, though they're exceedingly rare.
- quickben 9y agoMaybe pass them in a struct?
- CalChris 9y agoAs long as you give up all hope that you'll be passing values in registers.
- have_faith 9y agoAre there any languages where code-style is required to be a certain way? or it won't compile. I mean full authoritarian about everything, not just based around white-space like python.
- arghwhat 9y agoSome have little that can differ, such as assembly, but not that I know of at least. Some define a "proper" way, though (PEP-8, gofmt, and doesn't rust also have a rustfmt?).
- steveklabnik 9y agorustfmt exists, and has come a long way recently, but is not quite ready to be distributed with Rust by default yet. Soon though!
- mrec 9y agoI think the original question was about full-on enforcement of style rules as grammatical rules, by the compiler, as proposed by Ken Arnold in his 2004 essay Style is Substance [1]. AFAIK nothing like that is remotely on the cards for rustfmt. [1] http://www.artima.com/weblogs/viewpost.jsp?thread=74230 http://www.artima.com/weblogs/viewpost.jsp?thread=74230
- steveklabnik 9y agoAbsolutely.
- mmarx 9y agoThe gnat Ada compiler has style warnings, which, together with -Werror, ensure that you don't write non-conforming code.
- Athas 9y agoYes, old fixed-format languages like FORTRAN and RPG (the older versions). Everything had to be written in specific columns, due to their punched card heritage.
- chimprich 9y ago> A C programmer would call that variable tmp, which is much easier to write, and not the least more difficult to understand. Yuck. Abbreviations are usually bad. For one thing, people tend to pick different ways to abbreviate things so an hour later when you're trying to grep for where the variable was used you have to try to remember whether the variable was written tmp, temp, or temporary. In this example, "temporary" is probably the least useful thing to know about the variable, since most variables are temporary. How about "counter"?
- quotemstr 9y agoShort idioms are essential for concision in specific domains though. My favorite example: I was writing some graphics code recently, and some reviewer said: "I don't understand this uv abbreviation that appears all over the code. Please expand it." headdesk.gif (For those who aren't familiar: u and v are conventional names of texture coordinates, like x, y, and z are conventional names of spatial coordinates. There's no abbreviation to expand.)
- javajosh 9y agoI am sure you are right, but I can't figure out what "xy" would mean in a program, either. Perhaps all the points on a plane normal to z?
- krylon 9y agoI used to use x and y as my generic loop iteration variables until I worked on code that involved two-dimensional coordinates, and suddenly x and y had very specific meaning. I skipped to i and j, but I am certain there are mathematicians out there who find that confusing, too. I guess, it's about context, too, at least a little.
- lomnakkus 9y ago> I skipped to i and j, but I am certain there are mathematicians out there who find that confusing, too. IME it's pretty standard in most of mathematics to use "i" and "j" as index variables when e.g. doing sums and products over indices/sets. (Though I suppose you could be talking about the use of i, j, k as axes?)
- 2bluesc 9y agoI tend to follow these guidelines with the following exceptions: 1. always use curly braces 2. 4 spaces instead of a tab character
- wvenable 9y agoI violate #1 in only one case, the entire statement has to be one line: if (var1 != var2) return false; But having it on two lines and tabbed out without braces seems extremely ugly and dangerous to me.
- luckydude 9y ago100% agree with both points. Though I'm the crazy guy who does #define unless (x) if (!(x)) so I can do unless (f = popen("ps -axf")) die("popen of ps -axf");
- BenjiWiebe 9y agoI use a tab character with vim tabstop and shiftwidth set to 4.
- Unknoob 9y ago> Inconsistently using braces for function declarations. > Not using braces for conditions followed by single line statements. > Using abbreviations. This is enough for me to say fuck this guide.
- dom0 9y ago> Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged - the compiler knows the types anyway and can check those, and it only confuses the programmer. No wonder MicroSoft makes buggy programs. This refers to systems hungarian, the brain-dead twin of apps hungarian. The latter can be useful in C.
- quotemstr 9y ago"Apps Hungarian" is what happens naturally when defining meaningful variable names. You don't need to systematize it.
- greggman 9y agoThere are advantsges to systematizing it. https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/ https://www.joelonsoftware.com/2005/05/11/making-wrong-code-...
- dingo_bat 9y agoThe article has sentences like: > First off, I’d suggest printing out a copy of the GNU coding standards... Which suggests this was written from the point of view of a specific person. In which case, it should attribute the author somewhere. I couldn't find a byline anywhere. Also, no date.
- pritambaral 9y agoYou should run `git blame` on the file in the Linux repo.
- codefined 9y agoI think it's just trying to emulate a colloquial tone, actually being written by a number of individuals (or at least being updated by multiple people).
- antientropic 9y agoIt was originally written by Linus and is quite old (the line about burning the GNU coding standards was there in the first Git import [1], but IIRC it's way older). [1] https://github.com/torvalds/linux/blame/master/Documentation/process/coding-style.rst https://github.com/torvalds/linux/blame/master/Documentation...
- antientropic 9y agoLooks like it was introduced in Linux 1.3.53, which is from Jan 1996. http://lxr.linux.no/#linux-old+v1.3.53/Documentation/CodingStyle http://lxr.linux.no/#linux-old+v1.3.53/Documentation/CodingS...
- etqwzutewzu 9y ago"It’s a mistake to use typedef for structures and pointers." C programmers tend to forget this wise recommendation.
- Ace17 9y agoI have always though it was good practise (because it reduces the verbosity) ; Could you please prove me wrong? :-)
- luckydude 9y agoThe only thing I can think of is that you could have int mytype; conflicting with typedef struct { ... } mytype; By putting the "struct" in front you only potentially conflict with other struct definitions. Is that the thinking or is it something else?
- etqwzutewzu 9y agoYes, for pointer types for example type qualifiers (e.g., const or volatile) cannot penetrate typedef of pointer types. So if you use typedef with pointers you are stuck.
- dllthomas 9y agoIt varies a bit by context; Linus's call is likely the right one in the context of the kernel, though to be sure it's not so big a deal that other approaches can't be made to work fine. You call out one upside - decreased verbosity. The accompanying downside is usually - as in this case, for both structs and pointers - that potentially relevant information is made less visible. Whether it's a good idea depends on how likely that information is to be actually relevant, weighed against the upsides. Where performance is relevant, you want to be aware of where you're potentially passing large structs around. Putting this info in the type name instead is an option (eg _s), and can reduce verbosity a bit. I don't know of any good reasons to call out structs that are sized like primitives. The case against hiding pointers is much stronger. Level of indirection can be relevant to performance, and is often relevant to correctness, particularly where mutation is involved. You can put it in the type name, but it's not going to be any less verbose - a star is already one character. I allow a possible exception here for where an opaque type is allocated by a library and passed around as a handle and the client really doesn't need to ever know whether it's a pointer or an int index or what.
- quotemstr 9y agoThis coding style works, sure. But so does the NT kernel style, which is the opposite of Linux kernel style in many ways. For example, in NT, all structs and pointers are typedefs. So what? There's a certain elegance to type names being one token long. People bikeshed source code formatting. They make arguments about developer portability and visual minutiae, usually without any sort of evidence, when in reality the higher-level organization of the code matters a lot more. Optimizing code for readability quickly runs into diminishing returns and begins hurting a lot more than it helps. In general, I'm strongly against rules and ceremony and centralization when it comes to coding. Ostensibly, it's all about hygiene and best practices and whatever, but in practice this kind of discipline amounts to "I like it this way and you're going to like it too". It's far more important to let developers make decentralized, rapid decisions about the best approach for a particular task than to enforce some kind of useless Procrustean uniformity on everyone.
- remline 9y agoThe two styles work because they are not being mixed with their opposite. A cached shed optimization is what makes working with others bearable.
- Analemma_ 9y agoThat’s sort of what the parent is saying: “the only code formatting rule that matters is consistency, everything else is bollocks”. But people want to think there’s some kind of higher justification for their preferred style, so they come with these just-so stories that don’t have any real evidence behind them.
- quotemstr 9y agoAlso, it's local consistency is what matters, not global consistency. Developers can adjust to slightly different coding styles when they move to a new project. They're going to have to learn new abstractions, new bits of domain knowledge, and new coworker-interaction approaches anyway. Style is a very minor concern.
- 9y ago
- rawoke083600 9y agoI always "preach" the value is in uniformity ! Weather you camelCase or kebab-style or using my-super-foo-style as long as everyone on the team uses the SAME style. Thats a WIN ! THATS where the value is !! Not in the RIGHT style but in the SAME style.
- krylon 9y agoAmen to that! I have my preferences on where I place my curly braces, and I have strong opinions on camelCasing versus using_underscores. But for a given code base, consistency outweighs any advantages any given coding style might have. Also, emacs has glasses-mode, so when I have to work on a code base that uses camel case, at least I don't have to squint really hard. ;-)
- no_cake 9y agoIn case anyone is wondering if there's some kind of linter for these rules, you can use checkpath.pl https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl https://github.com/torvalds/linux/blob/master/scripts/checkp...
- Sir_Cmpwn 9y agoThe biggest take-away from this, in my opinion, is that it's better to just type `struct foobar` instead of typedefing `foobar_t`. Structs should be treated differently than scalars, and therefore you should write them differently. The #1 principle of any coding style should be to optimize for readability and clarity over writability and convenience. Also, please limit your lines to 80 characters. https://sr.ht/toyc.jpg https://sr.ht/toyc.jpg
- nitrogen 9y ago> 80 characters Assuming indentation is counted against those 80, why not use a bigger monitor?
- Sir_Cmpwn 9y agoDid you see my link? More practically, a lot of people (myself including) will split their monitor vertically to consider lots of code at once, and talk about code in emails via patches on mailing lists and such where 80 columns is the norm.
- mydeardiary 9y agoIt would be nice to have this integrated into clang-format.
- alexeiz 9y agoIt doesn't have to be integrated. It shouldn't be hard to produce a .clang-format configuration file for this coding style.