8 ms·
And this is why I hated learning C. You went through a 500 pages C programming book, did all the exercises, had a good grasp of the language but you were still
by olalonde 10y ago
And this is why I hated learning C. You went through a 500 pages C programming book, did all the exercises, had a good grasp of the language but you were still useless because you didn't know anything about those weird macros, Makefiles, automake, gcc flags, etc.
- tedunangst 10y agoThere's nothing particularly weird about this macro, and it has nothing to do with makefiles, automake, gcc flags, etc.
- ajkjk 10y agoIt is insane, though, and should have been replaced with a compiler feature to do static assertions twenty years ago.
- colanderman 10y agoIt was, five years ago. (C11 provides static_assert.) C was probably one of the first widely-used languages to support such a thing, beside Ada and C++.
- tedunangst 10y agoNo, Boost preprocessor is insane.
- ajkjk 10y agoWhy not both?
- viraptor 10y agoI agree that C is complicated, but this one has nothing to do with macros, flags or anything external. All you need to know to understand it is in the language itself. (Similar misunderstanding to the "down to operator" --> https://stackoverflow.com/questions/1642028/what-is-the-name-of-the-operator-in-c https://stackoverflow.com/questions/1642028/what-is-the-name...)
- olalonde 10y agoMaybe the book I read was not that good (Deitel&Deitel) but the section on macros was pretty tiny and I don't think I'd have understood that macro on my own. Anyways, I think C is great, just that most books don't seem to cover the important stuff to work on serious C projects.
- judahmeek 10y agoDeitel&Deitel make some amazing books as far as I'm concerned. They were my source material through college and a very enjoyable introduction to C, C++, and Java.
- colanderman 10y agoThe macro isn't the complicated part in the OP (`e` just gets substituted with whatever the argument is). The definition the macro generates is (for most cases, needlessly) complicated, but that has nothing to do with macros or the preprocessor. The general rules of macros are: 1. Don't use them; prefer static functions. 2. Use them as symbolic constants only. 3. Use parameterized macros only when you must use # or ## (i.e., for code abstraction), and then use them sparingly. 4. If you really insist, wrap every use of the arguments in parentheses, and be careful not to write the name of an argument somewhere where you don't mean it. You'll get pretty far knowing next to nothing about macros (e.g. expansion phases and tokenization rules) by following the above rules.
- anexprogrammer 10y agoI've never understood the feeling that C is complex. Simple syntax, simple rules, a few hidden gotchas for the unwary. "down to operator" = unhelpful use of whitespace. postdecrement x, check if >0 I still find C one of the easiest to pick apart. Obfuscated C entries excepted!
- patmcguire 10y agoOh man, wait until you find out about the Javascript ecosystem.
- olalonde 10y agoFunnily enough, I learned JavaScript about at the same time I learned C (~13 years ago) and at that time, JavaScript was dead simple to learn in comparison. I couldn't imagine myself trying to learn JavaScript today though, I'd probably be banging my head on walls.
- qb45 10y agofunction range_error_on_zero(x) {return Array(-!!x).length}
- kofejnik 10y agoFYI, this is valid js (equivalent to alert(1)): [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
- Immortalin 10y agoThat's why Go is so popular. It's the tooling and user experience that matters.
- hawkice 10y agoOr rather, it's why almost every popular tool is popular. Take Rails for instance. It's just that Go competes with C and boy howdy does the comparison look good to anyone who can make the switch.
- takeda 10y agoI'm not sure that macro in this submission shows that Go is better. Neither Go nor C has static assertions, the macro in questions uses clever techniques to implement one in C, but you probably can't do that in Go. So C is more powerful here. Another example of clever C macro use is implementation of foreach loop (C doesn't have foreach) in linux kernel, here's question about it: http://stackoverflow.com/questions/15754236/how-do-i-use-the-list-for-each-macro-in-list-h-from-the-linux-kernel-properly#15763938 http://stackoverflow.com/questions/15754236/how-do-i-use-the...
- cyphar 10y agoI don't agree that Go's tooling is what makes it popular. Mainly because it's tooling is not very good. All of the vendoring tooling is broken in one way or another, the linters and vet-checkers have questionable advice in some cases, and not to mention that the standard library has so many quirks that come from the fact that Go is trying to be system programming language that hides details about the system from you. [ Disclaimer: I'm a maintainer of runC and have been programming in Go for many years. But that doesn't mean I have to like the language. Give me C any day. ]
- johnfn 10y agoAnd then you look 10 characters to the left of the code and hey, there's the explanation to what it does!
- colanderman 10y agoBad C code is bad C code. There's equally bad JavaScript, Ruby, and Python code too; none of those languages have particularly simple semantics. Moreover, this particular example is due to compatibility issues across the multitude of platforms that Linux supports, necessitating support for versions of C older than any language you might like. Were Linux only ever to be compiled with a C11 compiler, this could be replaced with simply `static_assert(x)`. And speaking as someone who's coded C for 16 years and makes a living doing so: it is rare that I write a macro; my Makefiles are about 5 lines long; I've never touched automake; and the only GCC flags I ever use (and use consistently) are `-std=gnu11 -Wall -Werror -O3`. Heck I wrote a cross-platform NES emulator last month following these rules. There's a lot of bad C out there to find. Don't let that turn you off from writing good C.
- enraged_camel 10y ago>>Bad C code is bad C code. There's equally bad JavaScript, Ruby, and Python code too; none of those languages have particularly simple semantics. The problem is that C is in everything. OK, not literally, but you know what I mean. Bad JavaScript is easy to avoid. You just navigate to another website. Bad C though, not so much. Often times it's in the kernel or somewhere deep like that.
- pjmlp 10y agoAs a side effect of UNIX adoption in the industry. Like it happened with the browser and JavaScript, C got adopted thanks to UNIX. Before UNIX's adoption, many of us had a pleasant coding life using Turbo/Quick/Apple Pascal, Modula-2, Basic compilers.
- noir_lord 10y agoNo idea why you got so badly downvoted, your comment is pretty much spot on, bad C is hard to avoid.
- enraged_camel 10y agoI don't know either. It happens sometimes. I think it's just the bandwagon effect, and depends on the initial votes and their timing.
- simias 10y agoWhile this construct looks pretty weird if you decompose it element by element using the rules of the language it becomes rather clear IMO. The most arcane feature here is probably the bitfield syntax that you might not encounter very often in the wild. The problem with C IMO is that the compilers are very permissive by default and it's easy to trigger an undefined behaviour with seemingly harmless code if you're not careful. Things like promotion rules make it difficult to guess at a glance how the code is going to behave if you don't have a very good understanding of these (rather quircky) rules. There's also the whole mess of the pointer vs. array distinction which sometimes matter and sometimes doesn't etc... By comparison these BUILD_BUG_ON macros are relatively straightforward IMO. The naming is a bit misleading unfortunately but at least it's in full CAPS so you know it's a macro...