TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

How to C in 2016

1145 点作者 fcambus超过 9 年前

69 条评论

mapleoin超过 9 年前
<i>Writing correct code at scale is essentially impossible. We have multiple operating systems, runtimes, libraries, and hardware platforms to worry about without even considering things like random bit flips in RAM or our block devices lying to us with unknown probability.</i><p><i>The best we can do is write simple, understandable code with as few indirections and as little undocumented magic as possible.</i><p>Applies very well to all programming.
评论 #10866589 未加载
评论 #10864953 未加载
评论 #10864371 未加载
评论 #10864837 未加载
ddevault超过 9 年前
&gt;The first rule of C is don&#x27;t write C if you can avoid it.<p>Man, this is just lame. C is a really nice, useful language, especially if you learn the internals. It requires discipline and care to use effectively, but it can be done right. The problem is that a lot of C programmers only know C and can&#x27;t apply higher level concepts or abstractions to it because they&#x27;ve never learned anything else. This makes their code harder to maintain and easier to break.
评论 #10864548 未加载
评论 #10868364 未加载
评论 #10864531 未加载
评论 #10864893 未加载
评论 #10866965 未加载
_wmd超过 9 年前
Some of this seems like horrendously bad advice:<p>- Using fixed width integers in for loops seems like a fabulous way to reduce the portability of code<p>- the statements in &quot;C allows static initialization of stack-allocated arrays&quot; are _not_ equivalent, one is a bitwise zeroing while the other is arithmetic initialization. On some machines changing these statements blindly will cause a different bit pattern to end up in memory (because there are no requirements on the machine&#x27;s representations for e.g. integers or NULL or ..). There are sound reasons why the bitwise approach could be preferred, for example, because a project has debug wrappers for memset that clearly demarcate uninitialized data<p>- the statements in &quot;C99 allows variable length array initializsers&quot; aren&#x27;t even slightly equivalent. His suggestion uses automatic storage (and subsequently a stack overflow triggered by user input -- aka. a security bug)<p>- &quot;There is no performance penalty for getting zero&#x27;d memory&quot; this is bullshit. calloc() might optimize for the case where it is allocating from a page the OS has just supplied but I doubt any implementation ever bothered to do this, since it relies on the host OS to always zero new pages<p>- &quot;If a function accepts arbitrary input data and a length to process, don&#x27;t restrict the type of the parameter.&quot; the former version is in every way more self-documenting and consistent with the apparent function of the procedure than his use of void<i>. It also runs counter to a rule from slightly more conservative times: avoid void</i> at all costs, since it automatically silences all casting warnings.<p>Modern C provides a bunch of new things that make typing safer but none of those techniques are mentioned here. For example word-sized structs combined with struct literals can eliminate whole classes of historical bugs.<p>On the fixed width integers thing, the size of &#x27;int&#x27;, &#x27;long&#x27; and &#x27;long long&#x27; are designed to vary according to the machine in use. On some fancy Intel box perhaps there is no cost to using a 64bit type all the time, but on a microcontroller you&#x27;ve just caused the compiler to inject a software arithmetic implementation into your binary (and your code is running 100x slower too). He doesn&#x27;t even mention types like intfast_t designed for this case, despite explicitly indicating &quot;don&#x27;t write C if you have to&quot;, which in 2016 pretty commonly means you&#x27;re targeting such a device
评论 #10864974 未加载
评论 #10864778 未加载
评论 #10866776 未加载
评论 #10864903 未加载
评论 #10864728 未加载
评论 #10865318 未加载
AndyKelley超过 9 年前
The author linked to this site: <a href="https:&#x2F;&#x2F;www.securecoding.cert.org&#x2F;confluence&#x2F;display&#x2F;c&#x2F;SEI+CERT+C+Coding+Standard" rel="nofollow">https:&#x2F;&#x2F;www.securecoding.cert.org&#x2F;confluence&#x2F;display&#x2F;c&#x2F;SEI+C...</a><p>These are wonderful. Concise nuggets of knowledge that you can keep in your head, little warnings of what not to do.<p>Side note, it&#x27;s really fun reading this article about modern C given that I&#x27;m working on an experimental programming language meant to replace C [1]. Just today I got the Guess Number Game example working, without a dependency on libc [2] (caveat: Linux x86_64 only so far). So, I&#x27;m having fun trying to think about how C could be better, reading implementations of various libc functions, and writing my own &quot;standard library&quot;.<p>For example, in my language, there are no `int`, `unsigned char`, `short` types, there are only `i32`, `u8`, `i16`, etc (I shamelessly stole this idea from Rust). This mirrors the article&#x27;s suggestion to only use int32_t, uint8_t, int16_t, etc. But, since it&#x27;s a new programming language, we don&#x27;t have the other types sitting there as a red herring.<p>[1]: <a href="https:&#x2F;&#x2F;github.com&#x2F;andrewrk&#x2F;zig" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;andrewrk&#x2F;zig</a><p>[2]: <a href="https:&#x2F;&#x2F;gist.github.com&#x2F;andrewrk&#x2F;131e6f48a15c42fc5ca8" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;andrewrk&#x2F;131e6f48a15c42fc5ca8</a>
评论 #10864723 未加载
评论 #10864592 未加载
tines超过 9 年前
Most of this advice is pretty standard, but this stood out:<p>&gt; You should always use calloc. There is no performance penalty for getting zero&#x27;d memory.<p>But isn&#x27;t there? This may be true the first time the program requests a new page from the OS, but when your program starts reusing memory there&#x27;s going to be a performance hit.
评论 #10864462 未加载
评论 #10864331 未加载
评论 #10864845 未加载
annathebannana超过 9 年前
Terrible<p>The first rule of C is to ALWAYS use C<p>The second rule of C is to NEVER use [u]intN_t, use [u]int_leastN_t instead and (unsigned) char when you want to deal with bytes<p>The 3rd rule of C is to never use anything else when size_t should be used<p>The 4th rule of C is that everyone has his own style, so declaring variables on top is totally acceptable (and more clean IMO)<p>The 5th rule of C is &quot;enjoy your stack overflow&quot; when using VLAs instead of malloc (not to mention that VLAs are optional in C11)<p>&gt;which also means it&#x27;s capable of holding the largest memory offset in your program.<p>wrong<p>&gt;C99 gives us the power of &lt;stdbool.h&gt; which defines true to 1 and false to 0<p>I do use it but it is useless<p>&gt;readability-braces-around-statements — force all if&#x2F;while&#x2F;for statement bodies to be enclosed in braces<p>don&#x27;t use a shitty editor<p>&gt;You should always use calloc<p>good thing calloc has: checks for overflows when multiplying the typesize and the arraylen<p>bad thing: makes programmers think that it will make your pointers null<p>&gt;you can wrap it with #define mycalloc(N) calloc(1, N).<p>but the two arguments is the only good thing calloc has<p>&gt;growthOptional<p>I can&#x27;t see any reason why the second one is considered better
评论 #10866741 未加载
vitaut超过 9 年前
It&#x27;s a bit sad that the formatting API hasn&#x27;t improved in C over the years. Take this code, for example:<p><pre><code> printf(&quot;Local number: %&quot; PRIdPTR &quot;\n\n&quot;, someIntPtr); </code></pre> which is quite unreadable to say the least. To address this issue I even wrote a small library (<a href="https:&#x2F;&#x2F;github.com&#x2F;cppformat&#x2F;cppformat" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;cppformat&#x2F;cppformat</a>) that allows you to write something like this instead:<p><pre><code> print(&quot;Local number: {}\n\n&quot;, someIntPtr); </code></pre> It is written in C++ rather than C, because the latter doesn&#x27;t have facilities (at least overloading is necessary) to implement such library.
评论 #10868570 未加载
评论 #10869539 未加载
评论 #10870302 未加载
zrm超过 9 年前
The article says not to do this:<p><pre><code> uint32_t numbers[64]; memset(numbers, 0, sizeof(numbers) * 64); </code></pre> That is certainly true because that is a buffer overrun.
评论 #10867456 未加载
btrask超过 9 年前
I recently wrote a similar article (&quot;C Programming Substance Guide&quot;)[1] which made the rounds here[2]. I&#x27;ve updated and improved it quite a bit since then too. It seems like we agree on the major points but it might be a good second opinion.<p>[1] <a href="https:&#x2F;&#x2F;github.com&#x2F;btrask&#x2F;stronglink&#x2F;blob&#x2F;master&#x2F;SUBSTANCE.md" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;btrask&#x2F;stronglink&#x2F;blob&#x2F;master&#x2F;SUBSTANCE.m...</a><p>[2] <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=10157018" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=10157018</a>
to3m超过 9 年前
One point about char is that a pointer to a character type (character types are char, unsigned char, signed char - see 6.2.5.15) may alias non-char objects in a standard-compliant fashion (see 6.3.2.3.7). But uint8_t and int8_t may not necessarily be suitable replacements, because they are defined to be integer types (see B.19 - character types are a subset of integer types), and in any event may not even exist (7.20.1.1.3).
评论 #10867542 未加载
评论 #10868953 未加载
评论 #10868084 未加载
评论 #10864708 未加载
golergka超过 9 年前
As someone who has a been trying to get into modern C from higher level languages and looking for more modern sources than K&amp;R, THANK YOU. (Even if you just posted the link here and have no relation to original author). (Of course, this post is not the only place to learn about modern C, but still, a very useful one).
评论 #10864523 未加载
评论 #10864439 未加载
tsavola超过 9 年前
&gt; LTO fixes the &quot;source analysis and optimization across compilation units problem&quot; by annotating object files with intermediate representation so source-aware optimizations can be carried out across compilation units at link time (this slows down the linking process noticeably, but make -j helps).<p>make -j doesn&#x27;t help linking speed, unless multiple binaries are begin built.
评论 #10865006 未加载
评论 #10864543 未加载
deevus超过 9 年前
I wrote an assignment in C for Operating Systems in my second year of CS. I did it mostly for the challenge and ended up with a distinction grade.<p>It was very challenging! I was learning how to do threading in C for what was one of the most complex assignments in my degree. However, I don&#x27;t regret a moment of it. Even with a mark that was lower than my average programming assignment marks, I learned more in that assignment than I did in anything else while at uni.<p>Being forced to RTFM because it wasn&#x27;t abstracted away for you was exhilarating once I understood what was going on. And man, it was fast! Much faster than others who had programmed in Java.<p>I wish I had more reasons to write C, because I love it.
jhallenworld超过 9 年前
&gt;If you find yourself typing char [..] into new code, you&#x27;re doing it wrong.<p>&gt;The only acceptable use of char in 2016 is if a pre-existing API requires char (e.g. strncat, printf&#x27;ing &quot;%s&quot;, ...) or if you&#x27;re initializing a read-only string (e.g. const char <i>hello = &quot;hello&quot;;) because the C type of string literals (&quot;hello&quot;) is char </i>.<p>Heh, basically you need to use &#x27;char <i>&#x27; for strings. I would far prefer if strings were unsigned so that I could use &#x27;uint8_t </i>&#x27;, but if you try it you&#x27;ll get tons of conversion warnings and your code will look weird.
评论 #10865554 未加载
bluetomcat超过 9 年前
&gt; Use: &gt; ptrdiff_t diff = (uintptr_t)ptrOld - (uintptr_t)ptrNew;<p>The casts to uintptr_t are not needed in this case, as the result of subtracting two pointers already yields ptrdiff_t.<p>Also, the mere subtraction of two pointers that do not point to the same &quot;array object&quot; yields undefined behaviour as per the standard.
评论 #10866012 未加载
mrich超过 9 年前
Quite concise and short. Now wouldn&#x27;t it be great to also have such a short guide for C++... (thinking about the tome that is <a href="https:&#x2F;&#x2F;github.com&#x2F;isocpp&#x2F;CppCoreGuidelines" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;isocpp&#x2F;CppCoreGuidelines</a>)
评论 #10869676 未加载
评论 #10864944 未加载
评论 #10865025 未加载
Nursie超过 9 年前
Usually I find something very objectionable in these C guides, but I like this one, and it&#x27;s hit some of my favourite&#x2F;most hated bugbears. In recent years it&#x27;s nearly driven me mad seeing people use the old types either directly or re-implementing their own equivalent of stdint.h, complete with all sorts of platform switching and other nonsense.<p>We&#x27;ve got these facilities, they&#x27;re not exactly bleeding edge (the clue&#x27;s in the name C99), let&#x27;s use them!
评论 #10865334 未加载
haldean超过 9 年前
One trick I&#x27;ve been using a lot recently that saves me from forgetting to check error codes is the judicious use of __attribute__((__warn_unused_result__)) on functions that return an error code. It prevents you from being able to ignore the return value without doing something with it; even just assigning it to a variable and never checking the value in the variable isn&#x27;t enough to silence the warning.
agentultra超过 9 年前
Nice list!<p>I like using anonymous structs with variable initializers to provide parameters to functions with default values -- nice and clean!<p>C99 is not your grandparents&#x27; C. It has kept up with the times.<p>A more thorough resource I cannot recommend highly enough: 21st Century C[0]<p>[0] <a href="http:&#x2F;&#x2F;shop.oreilly.com&#x2F;product&#x2F;0636920033677.do" rel="nofollow">http:&#x2F;&#x2F;shop.oreilly.com&#x2F;product&#x2F;0636920033677.do</a>
vbezhenar超过 9 年前
How to C in 2016: use valgrind from the start. I think that it&#x27;s the best tool for C in the world.
评论 #10865351 未加载
jedisct1超过 9 年前
And then, someone points out that your code doesn&#x27;t work in Visual Studio, and that, of course, you have to support VS &lt; 2015.<p>So, you&#x27;re back to writing C89, in 2016.
评论 #10867978 未加载
tomcam超过 9 年前
For me, this is the most important bookmark of the year. Dropping back into C after using pre C11 it is tailor made for me. Covers all the areas I needed: Correct non-K&amp;R datatypes, new formatting options, best practices on arrays. Awesome.
jzwinck超过 9 年前
The clang-format wrapper script presented has a bug. The $@ at the end must be quoted for it to work on filenames containing spaces.<p>For bonus points it shouldd prefix the clang-format command with &quot;exec&quot; but that&#x27;s not a correctness issue.
评论 #10870988 未加载
camgunz超过 9 年前
I refuse to believe that the wicked Buffer Overflow has completely stymied humanity. Use array&#x2F;string&#x2F;buffer libraries. They&#x27;re very small and very easy to test. Pass them around instead of a &quot;char *&quot; and a &quot;size_t&quot;.<p>Now, if you want to talk about signed overflow, bitwise operations on signed types, wacky undefined behavior, or memory management, that stuff is pretty hard to deal with in C. But 99% of the time when people are shaking their fists at &quot;shitty ol&#x27; C ruining the Internet for everyone&quot;, they mean buffer overflows, and it just shouldn&#x27;t be an issue these days.
hyc_symas超过 9 年前
The biggest failure of this article is the multiple admonishments &quot;never do &lt;blah&gt; (except for this, this, and that other case over there&quot; - all advice of this form is worthless when your supposed thesis is making code readable and consistent.<p>Consistency means avoiding special cases. Variable length arrays are too prone to special cases - IMO, just don&#x27;t use them. malloc vs calloc is too prone to special cases, that rule is worthless. The rule &quot;never use memset&quot; is full of special cases, also worthless. (And in fact, for your larger automatic initializations, gcc just generates code to call memset anyway.) I would say &quot;always use memset when you need zeroing - then you&#x27;ll never be surprised.&quot; The fewer special cases you have to keep track of, the better.<p>&quot;Never cast arguments to printf - oh but for %p, always cast your pointers to (void *)&quot; again, worthless advice with an unacknowledged special case.<p>The way to write code that always works right is to always use consistent methodology and avoid any mechanism that is rife with special cases.<p>The advice &quot;always return &#x27;true&#x27; or &#x27;false&#x27; instead of numeric result codes&quot; is worthless. Functions should always return explicit numeric result codes with explicitly spelled out meanings. enum is nice for this purpose because the code name is preserved in debug builds, saves you time when working inside a debugger. But most of all, it&#x27;s a waste of time for a function to return a generic false&#x2F;fail value which then requires you to take some other action to discover the specific failure reason. POSIX errno and Windows GetLastError() are both examples of stupid API design. (Of course, even this rule has an exception - if the function cannot fail, then just make it return void.)
mrcrassic超过 9 年前
&gt; C99 allows variable declarations anywhere<p>I actually like declaring my variables at the top. To me, this seems more readable than searching for declaration statements throughout the code.<p>Why should I not do this?
评论 #10865338 未加载
评论 #10865518 未加载
评论 #10866512 未加载
cpeterso超过 9 年前
This article focuses on clang and gcc, but note that MSVC&#x27;s printf functions do not support %zu (or %zd) for size_t. MSVC uses %Iu. There is no standard &quot;PRIuSIZE&quot; macro for size_t, but Mozilla defines a polyfill for Firefox:<p><a href="https:&#x2F;&#x2F;hg.mozilla.org&#x2F;mozilla-central&#x2F;file&#x2F;tip&#x2F;mfbt&#x2F;SizePrintfMacros.h" rel="nofollow">https:&#x2F;&#x2F;hg.mozilla.org&#x2F;mozilla-central&#x2F;file&#x2F;tip&#x2F;mfbt&#x2F;SizePri...</a>
xedarius超过 9 年前
I don&#x27;t think the claim of zero performance penalty for calloc is true. If for example you&#x27;re calling calloc on a game console it is 100% not true.
roberthahn超过 9 年前
In light of the fact that best practices have evolved considerably since K&amp;R, what book(s) would you recommend for people wanting to learn C today?
评论 #10868395 未加载
评论 #10865746 未加载
评论 #10868050 未加载
slmyers超过 9 年前
Fantastic article. This is exactly how the language should be taught in university. At least I wish I was taught to code like this in school.
评论 #10867925 未加载
tptacek超过 9 年前
Is there any moral difference between using VLAs and calling alloca? Because alloca is generally recognized as evil.
评论 #10868170 未加载
评论 #10866134 未加载
评论 #10866697 未加载
tilt_error超过 9 年前
Having worked with a large code base, maintained over a period of time (25+) by multiple persons has learned me respect and that even old code have a value in virtue of being running without problems over time. A piece of software that is running without problems has a value in itself that have to be taken into account when considering the cost of maintenance.<p>Respect earlier developers and try to minimise _unnecessary_ changes that break version control history. Did earlier developers use names you don&#x27;t like? Formatting you don&#x27;t like? InconsistentCamelCasing or other_naming_paradigms you don&#x27;t like? Let it be -- at least until you do a refactoring where _you_ claim responsibility.<p>It may not be a good point to uncritically and retroactively apply the good points from the original article in an old code base.
Xophmeister超过 9 年前
I thought `ssize_t` was only signed `size_t` in practice. Technically, it only needs to be `size_t` with -1.
评论 #10868888 未加载
Joky超过 9 年前
C (or C++) in 2016 and no mention of ASAN&#x2F;UBSAN(&#x2F;TSAN)? This seems like a must nowadays.
synack超过 9 年前
Would love to see a discussion of build systems for modern code. Trying to decide between autoconf&#x2F;cmake&#x2F;scons&#x2F;ninja&#x2F;gyp for new projects is like flipping a coin... They all have their advantages and disadvantages and there is no clear winner.
rwmj超过 9 年前
After too many problems with &quot;unfriendly C&quot;, I finally gave in and now compile everything with -fno-strict-overflow (the Linux kernel does the same thing). I don&#x27;t care about architectures that don&#x27;t use twos-complement.
justncase80超过 9 年前
For an example of a high quality modern C api I highly recommend taking a look at libuv:<p><a href="http:&#x2F;&#x2F;libuv.org&#x2F;" rel="nofollow">http:&#x2F;&#x2F;libuv.org&#x2F;</a>
mmphosis超过 9 年前
# cc test.c -o test -O3 -Os -Wall -pedantic -Werror -Wshadow -Wstrict-aliasing -Wstrict-overflow -std=c99<p>test.c:1:2: error: #import is a GCC extension
评论 #10866481 未加载
csvan超过 9 年前
&quot;The first rule of C is don&#x27;t write C if you can avoid it.&quot;<p>This ought to carved into the walls of R&amp;D departments everywhere.
评论 #10864444 未加载
评论 #10864420 未加载
peter303超过 9 年前
2016 is my 40th year of using C. I prefer Java.
dllthomas超过 9 年前
My biggest tip for writing maintainable C for modern compilers is to avoid passing bare primitives between functions. Don&#x27;t just typedef - wrap things in (single-element) structs that describe the contents. The compilers these days understand that they can boil off the wrapper when generating code.
muricula超过 9 年前
Is it better to fully qualify structs and unions or to hide their names by typedefs? I frequently see people hide all struct types because it&#x27;s visual clutter and extra typing. In other words, given some struct a, should I do: typedef struct a a_t;<p>I realize this is a bit of a style question, but I&#x27;m curious.
评论 #10869409 未加载
cpeterso超过 9 年前
clang has a -Weverything flag that, unlike &quot;-Wall&quot;, will enable <i>all</i> compiler warnings. This includes possibly contradictory warnings. :) For new C code, -Weverything is a good place to start.<p>Unlike gcc, clang does not have good documentation for its warning options. The best sources I&#x27;ve found are the clang code itself (<a href="https:&#x2F;&#x2F;github.com&#x2F;llvm-mirror&#x2F;clang&#x2F;blob&#x2F;master&#x2F;include&#x2F;clang&#x2F;Basic&#x2F;DiagnosticGroups.td" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;llvm-mirror&#x2F;clang&#x2F;blob&#x2F;master&#x2F;include&#x2F;cla...</a>) and <a href="http:&#x2F;&#x2F;fuckingclangwarnings.com&#x2F;" rel="nofollow">http:&#x2F;&#x2F;fuckingclangwarnings.com&#x2F;</a>.
legulere超过 9 年前
I would add:<p>- Add security measures provided by your compiler to your builds: -fstack-protector-strong on GCC. -fsanitize=safestack on Clang if you have a version that&#x27;s new enough.<p>- Build the program with AddressSanitizer and run it with typical data. Run it through a fuzzer afterwards.
jhallenworld超过 9 年前
C should have an inferred integer type:<p>for (infer x = 0; x != 10; ++x) ...<p>If the compiler can infer the type, use the fastest integer. If it can not infer, use the largest integer.<p>I&#x27;m sure this would create difficulties with structs, but at least for local integers it would be nice.
评论 #10865176 未加载
评论 #10868825 未加载
wyldfire超过 9 年前
&gt; For modern programs, you should #include &lt;stdint.h&gt; then use standard types.<p>Unless you&#x27;re doing memory-mapped IO, or other very-specific things, you probably only need the <i></i>_least_t or <i></i>_fast_t types (int16_least_t, e.g.).
admax88q超过 9 年前
&quot;How to C in 2016&quot; Don&#x27;t. C has outlived its usefulness. It&#x27;s time to move on to more expressive languages. The fact that buffer overflows are still a thing in 2016 should be an embarrassment to the industry.
评论 #10869867 未加载
评论 #10868159 未加载
kardos超过 9 年前
&gt; Formatting<p>&gt; The solution here is to always use an automated code formatter.<p>Spot on. Python got that part right.
评论 #10865233 未加载
评论 #10864995 未加载
ape4超过 9 年前
&gt; It&#x27;s important to not remain stuck in your &quot;things I learned in the 80s&#x2F;90s&quot; mindset of C development.<p>Instead use C99 ... which is from 1999. (Yes, I know most people didn&#x27;t learn it in the 90s)
评论 #10869156 未加载
lephyrius超过 9 年前
&quot;generally you want -O2&quot;<p>I see this a lot shouldn&#x27;t O3 produce better optimizations? Is that people have large codebases? OR is it that O3 does some CPU&#x2F;memory tradeoffs? OR something else?
评论 #10865332 未加载
评论 #10864654 未加载
caf超过 9 年前
The article seems to be implying that you should use both -O2 and -Os, but these are mutually exclusive options - if you supply both, only the last one specified has effect.
jhallenworld超过 9 年前
-Wextra is not enough. Should also have: -Wconversion and -Wstrict-overflow=4<p>In some ways -Wextra is too much: it&#x27;s annoying that -Wall with -Wextra complain about unused parameters.
asveikau超过 9 年前
Never use int? Use uint8_t instead of char for strings? These are not best practices, this is a lot of terrible advice that will make many c people laugh at you.
cptaffe超过 9 年前
&gt; #define mycalloc(N) calloc(1, N)<p>I am not a fan of the use of macros here. You should never use macros.<p>Instead maybe: static inline void *mycalloc(size_t sz) { return calloc(1, sz); }
评论 #10865723 未加载
aback超过 9 年前
&gt; There&#x27;s not much room for &quot;casual observer C development.&quot; For the rest of the world, that&#x27;s why we have Erlang.<p>lmaoed at that one
typon超过 9 年前
C Programmers bragging about writing good C in this thread is just funny. A large majority of new code does NOT need to be written in C. There&#x27;s nothing extra-ordinary about knowing how to write C. Learn to write HDL if you want to brag.
ChuckMcM超过 9 年前
Since I like coding in C, I am mildly offended by the notion that you should not write code in it, but I really enjoyed that all of these things were put together in one place.
kenOfYugen超过 9 年前
<p><pre><code> &gt; Standard c99 </code></pre> If you have to write C, why not go with ANSI C&#x2F;C89 for compatibility&#x2F;portability reasons?
评论 #10867495 未加载
atemerev超过 9 年前
Oh my goodness, so true.
jrcii超过 9 年前
Learning C is intimidating to me because every time I see a post written by a long-time C programmer, there are 10 more long-time C programmers explaining how the post is incorrect. Most C books on Amazon have reviews wherein credible-sounding programmers criticize the mistakes of the author.<p>If publishers and programmers with popular blogs can&#x27;t get a consensus on what constitutes correct C, how could I ever hope to produce it?<p>Case in point <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=10864601" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=10864601</a>
评论 #10871935 未加载
评论 #10869257 未加载
ue_超过 9 年前
&gt;If you find yourself typing char or int or short or long or unsigned into new code, you&#x27;re doing it wrong.<p>int is a type that&#x27;s at least 16 bits large. I can&#x27;t see the problem with using it. If I specify that I want a type that&#x27;s 32 bits large, my code won&#x27;t run on 16 bit systems.<p>Why should I assume? Because the author doesn&#x27;t believe in writing code that works on &quot;20 year old systems&quot;?
评论 #10864440 未加载
评论 #10864363 未加载
评论 #10864549 未加载
评论 #10864602 未加载
SFjulie1超过 9 年前
Advice forgotten: - you should always avoid library whose API documentation are unaccessible or poorly written; - unix man page is a great format but windows has good help format too (synopsis, signature, use case, error handling, meaning of constants, caveats), - always check every function you are using from time to time ... human memory is not perfect, even open&#x2F;calloc ....; - don&#x27;t copy paste example code blindly from man or stackoverflow ... (I remember windows C++ doc having horrible example with bugs);<p>Have a reference to the norm easily accessible and don&#x27;t use options of the compiler which impact you don&#x27;t fully know.<p>Most developer are poorly understanding multithreading and it can be tricky to make a portable library that has this property. Don&#x27;t hesitate to stipulate in your documentation that you did not cared about it, people can then use languages with GIL (ruby, python ...) to safely overcome this issue.<p>Modern language are social, take advantage of sociability (nanomsg, swift, extension, #include &quot;whatever_interpreter.h&quot; ....).<p>Programming in C with dynamic structures is guaranteed to be like a blind man walking in a mine field: you totally have the right either to make C extension to modern language OR include stuff like python.h and use python data structure managed by the garbage collector from C.<p>Old style pre allocated arrays may not be elegant, but that&#x27;s how critical system avoid a lot of problems.<p>DO NOT USE MAGIC NUMBERS...<p>USE GOTO for resource cleaning on error and make the label of the goto indentend at EXACTLY the same level the goto was written, especially when you have a resources that are coupled (ex: a file and a socket). Coupling should be avoid, but sometimes it cannot. Remember Djikstra is not that smart, he was unable to be a fully pledged physicist that can deal with the real world.<p>Avoiding the use of global variable is nice, but some are required, don&#x27;t fall for the academic bias of hiding them to make your code look like it has none.<p>Copy pasting function is not always stupid (especially if you use only 1 clearly understandable function out of a huge library).<p>Be critical: some POSIX abstraction like threads seems to be broken by complexity: KISS.<p>Modern C compiler are less and less deterministic, learn about C undefined behaviour and avoid clang or GNU specific optimisations and CHECK your code gives the same results with at least 2 compilers.<p>Don&#x27;t follow advices blindly: there are some C capos out there that dream an ideal world. Code with your past errors in mind and rely on your nightmarish past experiences to guide you to avoid traps. Feeling miserable and incompetent is some time good.<p>Resources are limited : ALWAYS check the results of resource exhaustion in C instead of relying on systems and always have error messages preallocated and preferably don&#x27;t i18n them. Don&#x27;t trust the OS to do stuff for you (closing files, SIGSEV&#x2F;SEGFAULT ...).<p>KISS KISS KISS complexity is your enemy in C much more than in other languages. Modern C&#x2F;C++ want you to build complex architecture on libraries that are often bloated (glibc).<p>Egyptians are nice looking.<p>Once you finished coding you have done only the easy part in C: - dependency management is hard in C; - have a simple deterministic build chain; - you should write your man pages too; - you should aim at writing portable code; - static code analysis, maybe fuzzing, getting rid of all warnings is the last important part.<p>Coding in C is just about 15% of the time required to make great software. You will probably end up debugging it much more than you write it: write code for maintainability as your first priority and do not under any circumstances think that you can handle multiple priorities (memory use, speed, ...).<p>Above all : just write maintainable code, please. This rule is the golden rule of C and it has not changed.
评论 #10869061 未加载
Kenji超过 9 年前
Wow, I wish I knew all of this when I started a big project last year... It&#x27;s kinda hard to change it NOW. And with that I mean it would be endless rewriting of the entire thing.
J_Darnley超过 9 年前
&gt; You continue arguing, &quot;on a 32 bit patform I want 32 bit longs and on a 64 bit platform I want 64 bit longs!&quot;<p>Ha ha ha. What kind of programmer would argue this? Do they ignore Windows 64? The type long is 32 bits there.
shusx1234超过 9 年前
a rubbishy article
admax88q超过 9 年前
&quot;How to C in 2016&quot; Don&#x27;t.
plg超过 9 年前
&quot;Notice we don&#x27;t have char anymore. char is actually misnamed and misused in C.&quot;<p>so defining a string happens how if not:<p>char *my_string = &quot;Hello&quot;;
评论 #10864360 未加载
评论 #10864707 未加载
kazinator超过 9 年前
&gt; <i>Standard C99</i><p>No thanks; sticking to C90.<p>&gt; <i>LTO</i><p>Violates ISO C, which says that semantic analysis is done in translation phase 7, and only linking takes place translation phase 8.
评论 #10865781 未加载
forrestthewoods超过 9 年前
&quot;The first rule of C is don&#x27;t write C if you can avoid it.&quot;<p>Eek! Not what I was expecting. In the video game world there is a not so small contingent of &quot;write everything in C unless you have a really damn good reason not to&quot;.<p>Great post though. Now go forth into the world and write C, my friends!