10 ms·
Humans should think of sizeof() as a function, says Linus Torvalds
- mburns 11y ago(2012)
- lazzlazzlazz 11y agoWho the hell doesn't think of `sizeof` as a function?
- Luc 11y agoI learned C from 'Kernighan & Ritchie', where it's never referred to as a function but as a compile-time operator. I've never thought of it as a function.
- deleted 11y ago[deleted]
- _lce0 11y agoWell it's an operator, and algebra said all them are just functions... Just like `+` is a function Anyways not all those writing code have CS background
- masklinn 11y agoExcept sizeof is a compile-time operation, not runtime. If sizeof were a function, int *foo = malloc(sizeof(*foo)); would make no sense.
- rdc12 11y agoSo in practice it works more like a C Macro then a C function? Edit, except it doesn't treat arguments the same, so no.
- cygx 11y agoIt's neither: sizeof belongs in its own category of unary compile-time(-ish) operators, whose only other member is _Alignof. If you're so inclined, you might add _Generic and _Pragma to that mix as well, but they aren't really a close fit.
- barrkel 11y agoCompile-time functions are a thing. Not in C, but in other languages, including C++. This all comes down to what you think "function" means. If you're living in a C bubble, of course sizeof isn't a function. If you have a wider mapping (!) for the word, then it is a kind of function.
- mcguire 11y agoIf you think everything called a "function", in every context, is the same thing, you are going to have a very bad day.
- userbinator 11y agoIn C99, sizeof is compile-time only if VLAs are not involved. In C89, sizeof is always compile-time.
- weland 11y agoExcept algebra said that about algebraic functions and operators. I know a CS major who insisted in pointing out the same thing. He was extremely surprised when dragons hatched from his eggs instead of the chickens he expected. It was a really heated event. He barely escaped -- and then ranted for several weeks how they were really just eggs and couldn't explain what happened.
- noselasd 11y agoIt's an unary operator, with 2 forms: sizeof(type) or sizeof expression but e.g. unlike a function, it doesn't evaluate the expression. sizeof(my_function()) doesn't call my_function. sizeof(a = 12) doesn't assign 12 to a.
- Retr0spectrum 11y agoSo is "sizeof(a = 12)" equivalent to just "sizeof(a)"?
- hebdo 11y agoWell, `a` could overload the "=" operator, in which case you would get `sizeof(a.operator=(12))`. But as far as pure C goes I believe you are right. Edit: Via the C99 spec (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf). The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant. The type of an assignment expression is the type of the left operand unless the left operand has qualified type, in which case it is the unqualified version of the type of the left operand. So it is indeed the case that `sizeof(a = 12)` is equivalent to `sizeof(a)` in the C world.
- to3m 11y agoAn interesting result of this (I suppose...) is that if a macro expands an argument twice, and one of those times is an operand for sizeof, you don't need to mention the double expansion in the documentation.
- lazzlazzlazz 11y agoThat's a language design choice - not a conceptual argument.
- krylon 11y agoIIRC, if the argument to sizeof is a type, the parentheses are mandatory, anyway, so using it like it was a function is more consistent. I think the reason it is not a function from the standard's point of view is that C does not have any builtin functions (unless my memory totally fails me in this case), all functions have to be either defined locally or #included.
- netheril96 11y agoExactly. I heard people arguing on the Internet that you should not add parentheses when sizeof is applied to an expression, only a type. I just cannot understand why they bother. Just add a parenthesis and it is always right. Much less cognitive burden.
- raverbashing 11y agoThis is the same people that find it "better" to write JS without the semicolons.
- deleted 11y ago[deleted]
- Negative1 11y agoI don't believe its equivalent. When I'm writing Scala code in the backend and have to switch to frontend I often find myself omitting the semi-colons but going back and fixing due to self-imposed coding conventions. For Javascript just as in Python or Scala, semi-colons are optional for a good reason.
- raverbashing 11y agoWell, semicolons may be optional in Python but the official python style strongly recommends agains (needing to use them) It's not about forgetting them once in a while, it's about playing a game of "needs a semicolon or doesn't" which increases the (already high) number of things the developer needs to worry about
- Udo 11y agoI'd like to confess that I'm one of the return() people, and I also do if() even in cases where the language doesn't require it. This behavior isn't borne out of confusion about what is and what isn't a special language construct. Rather, it helps me prop up the illusion that programming is about using a few simple primitives instead of being the chain of compiler directives it actually entails - it's an esthetic choice if not always a logical one. The thought that if() could just be a lazily-evaluated function taking a code block argument, and that return() could be a way of marking the end result of an expression somehow pleases me. I think the different expectations about sizeof() come from the artificial distinction between operators and functions, the implication being that in a compiled language the sizeof operator would be a compile-time construct, or barring that, at least a behavior of the type system. On the other hand, there are tons of compiler intrinsics in C/C++ that look exactly like functions but aren't.
- sedeki 11y agoDoesn't `if` always require parenthesizes?
- elisee 11y agoYes, in C, but I believe Udo was talking about other languages (like Go for instance) > and I also do if() even in cases where the language doesn't require it This sentence could be parsed in multiple ways though :)
- zoul 11y agoNot in all languages. For example, Go and Swift don’t require it.
- Udo 11y agoNo, not always. Not in Go, or in Rust, or Ruby, for example. The assumption being in these languages that if is followed by an expression and that expression is parsed to its natural end anyway - but this only works if the syntax allows for that end to be found without ambiguity.
- 11y ago
- soup10 11y agoWhat kind of monsters don't use parentheses on sizeof. Is it the same guys that put { on new lines and have giant comment templates for every one line function.
- michaelmior 11y ago{ on new lines seems to have dominated the majority of code I've worked with although I've always preferred putting it on the same line myself.
- pivo 11y agoI put it on the line that makes the code following it the most clear
- MrBuddyCasino 11y agoHow do you handle auto-format? If a rules doesn't survive that, its not practical, at least for me.
- pivo 11y agoWe don't use auto format for one because as far as I know it's not available for our languages (objective-c and swift)
- deleted 11y ago[deleted]
- vidarh 11y agoI've never met an auto-formatter that I haven't hated the output of enough to not use it.
- MrBuddyCasino 11y agoWhich ones would that be? The Eclipse one has a million knobs and twiddles, and is bearable in 95% of the time after fiddling with them a lot, which I'm okay with.
- progrn 11y agoBut, I cannot get a function pointer to it, right?
- krylon 11y agoExactly.
- fnthrowa98 11y agoIt is a function in the mathematics sense, not the C sense.
- wz1000 11y ago> "return()" is in no way a function. Ah, but in Haskell, `return` is a function, though it shares only a few similarities with with its counterpart in C-like languages. However, when using continuations or a continuation passing style, the continuation is a function that behaves almost exactly like traditional return when called! (define (multiply x y return) (return (* x y)))
- mattkrea 11y agoJust as annoying as people not using parens with "typeof()" in JavaScript.
- Negative1 11y agoI respect Linus greatly but the way he to talks to his fellow 'humans' is insanely confrontational, rude and disrespectful. It overshadows his arguments (which are usually very good) and throws people on the defensive. I'm grateful for all he has accomplished and shared with us but I imagine working with him is 'hell'.
- moonbug 11y agoAgreed. Not sure which is worse - that he's a terrible role model, or that he's proud of that fact.
- topkekz 11y agohttp://www.catb.org/esr/faqs/smart-questions.html#keepcool http://www.catb.org/esr/faqs/smart-questions.html#keepcool
- douche 11y agoI would imagine once you get used to him and thicken your skin up a bit, it's no big deal. Hell, a little salty language and telling people they're being idiots when they are being idiots is not a bad thing. The best machinists and millwrights I've worked with were like that, and it was a good thing - you don't have time to ask politely when there are steal beams or a two-ton electric motor swinging towards you. C can be almost as dangerous :-)
- twerquie 11y agoHe literally says that those who disagree with his code style should be shot. That's completely unacceptable language to use and makes him sound like he hasn't mastered English. I'm not sure anyone should take c-language style tips from such a boor.
- nmj 11y ago> Here's an example of a really bad use of "sizeof" that doesn't have the parenthesis around the argument: sizeof(*p)->member. Quite frankly, if you do this, you should be shot. Good ol' Linus
- thomasahle 11y agoI certainly read that the wrong way first time around.
- moonbug 11y ago"Quite frankly, if you do this, you should be shot. " Ah, yes. No comment from Torvalds is complete without a gratuitous ad hominem.
- falcolas 11y agoTo be fair, he's referring to the code `sizeof(*p)->reference`, in which case I'd probably shoot the writer too.
- sfk 11y agoI'm sure he'd appreciate a memo from Sam Altman about gratuitous negativity.
- loup-vaillant 11y agoThis is not an ad hominem argument. This is merely blowing things out of proportion. This would be ad hominem (and non-sequitur): "You're watching dancing bunnies, and you dare suggest we should remove the parens after sizeof?" Attack on the person (watching dancing bunnies), used to discredit an unrelated opinion (parens after sizeof).
- gpvos 11y agoI used to write return (0); I.e., with a space. I'm not sure if someone ever told or recommended me to do this, but the reason I did this was consistency with other C statements, because all C statements that take some kind of expression as a parameter (if, for, while) require it to be surrounded by parentheses. So it seemed logical to me to do the same with return. I've stopped doing it now, although some of the old code still lives. I've seen code by others where there was always a space between the function name and its arguments. That was ugly, and really confused a function call with a statement.
- krylon 11y agoI find parens around a return value/expression slightly annoying, but not annoying enough to have a debate over it. It doesn't make the code harder to read, IMHO. Whitespace between a function name and the arguments is significant, however, because with a function-like macro, there must be no whitespace between the name and the opening parenthesis. I've seen the following code in production code, for example: #include <stdlib.h> #define free(x) free(x), x = NULL free(ptr1); // Macro free (ptr2); // Call free(3) directly (Whether or not such a macro is good idea is a different question entirely, the point is that you can prevent such macro-expansion by using whitespace. Aesthetically, I find it very disturbing, though.)
- rwallace 11y agoYou do need to omit whitespace between the name and the opening parenthesis when defining a functionlike macro, but it doesn't matter when you're calling it.
- krylon 11y agoI furiously looked at the C standard (C99, anyway) and the documentation to the gcc preprocessor, and have to admit somewhat embarassedly, that you are right. The gcc preprocessor documentation clearly states: > "If you use the macro name followed by something other than an open-parenthesis (after ignoring any spaces, tabs and comments that follow), it is not a call to the macro, and the preprocessor does not change what you have written." Thanks for pointing this out to me!
- tormeh 11y agoWhy is this important?
- kazinator 11y agoYes, return can be a function. Torvalds hasn't heard of continuations, obviously, where we "return" from a function by invoking a continuation. We can justify writing return (expr); using the same arguments that justify the sizeof (expr) convention. The thing is that in C, return isn't a function; there are no continuations. Similarly, sizeof is an operator, which doesn't reduce its argument expression to a value. If we are going to make coding conventions based on pretending that C is a different language in which sizeof is a function, then pretending return is a function is also fair game.
- hueving 11y agoHe is talking about C. Continuations are irrelevant.
- kazinator 11y agoThat point is clearly made in the comment you're replying to, with the additional point that if we are talking about C, then sizeof is an operator, not a function. It doesn't require parentheses, except when its operand is a type expression. No well-considered coding convention requires superfluous parentheses with sizeof, and there are good reasons to ban them. We should prefer code like: type *ptr = malloc(sizeof *ptr); /* no parens */ to type *ptr = malloc(sizeof (type)); In general it's often better to base sizeof on an ordinary expression rather than a type expression. If we don't use superfluous parentheses on sizeof, we can then look for sizeof followed by an open parenthesis to look for code where sizeof is applied to a type expression. sizeof (type) means "produce me a size_t value based on some arbitary type, without checking that it's related to anything in the surrounding code". It can be as dangerous as a (type) cast.
- anonbanker 11y agoWhy shouldn't return be considered a function?
- newuser88273 11y agoScheme has come up with the idea of pretending that an undelimited contination is a function, which is somewhat true-ish... in the degenerate sense of a function with empty domain. This is fine for Scheme, which is an expression language, so every method of invoking a continuation would, syntactically, be an expression anyway. In C, which has statements, making return look like an expression is somewhat pointless. It doesn't matter whether C "has" continuations (and it arguably has) or not.
- Chathamization 11y agoI first learned that sizeof was an operator when I was confused about how it dealt with arrays compared to functions. After I learned it was an operator and not a function things made sense and were (relatively) consistent again. Several commentators here have given other examples where you will be completely thrown off if you believe that '"sizeof()" really is a function.' The problem with "lies to children" is that they can pile up to the point where people end up becoming completely confused about what's actually happening. As the internal inconsistencies mount, the "simple" lie starts to become a lot more complex than the "complicated" truth.
- tvb 11y agoMakes a good C interview question: char c; short h; int i; char *s; 1 = sizeof (char) 2 = sizeof (short) 4 = sizeof (int) 4 = sizeof (float) 8 = sizeof (double) 1 = sizeof (c) 2 = sizeof (h) 4 = sizeof (i) 4 = sizeof (s) 4 = sizeof &c 1 = sizeof c 2 = sizeof h 4 = sizeof i 4 = sizeof s 1 = sizeof *s 4 = sizeof &main 4 = sizeof (sizeof (i)) 4 = sizeof (sizeof i) 4 = sizeof sizeof i 4 = sizeof sizeof sizeof i from: http://leapsecond.com/tools/size1.c http://leapsecond.com/tools/size1.c