Live data from Hacker News

There is no 'printf'

netmeister.org

41–50 of 158 posts

Re: There is no 'printf'

#41

Quick Summary: The C compiler optimizer replaces printf("Hello World!\n") with puts("Hello World!\n") and the implicit return from main() changes from 13 (the return value of printf) to 10 (the return value of puts)

Calls on puts you say?

In other words long volatility

Re: There is no 'printf'

#42
post #40

Earlier quoted context omitted.

OK, those are horrifying and fascinating, and they basically break my brain. Is there a explanation somewhere of why the first one "works"? The second one I think is the compiler assuming the default case will never be hit since it'll result in infinite recursion, which is UB under C++, so it's basically assuming 0 The first one I'm less certain about. The only thing I can think of is that the compiler deduces an upp…

Optimizers have to keep the same input/output pairs unless there is undefined behavior. In the second function the truth table looks like: in | out ---------- 0b000 | 1 0b001 | 0 0b010 | 1 0b011 | 0 0b100 | don't care . . . MAX | don't care The compiler just chooses the most efficient way it knows to get the filled out entries correct which happens to be: in | ~in[0] ---------- 0b000 | 1 0b001 | 0 0b010 | 1 0b011 | 0…

The first function (the `n == 0 || !isEven(n+1)` recursive function) has defined behavior for negative numbers. That's probably why it compiled to an even number check.

Re: There is no 'printf'

#43
post #17

So, why does puts do "return r ? EOF : '\n';"? Some backwards compatibility? Or is there a logical reason for that?

That particular implementation probably returns the result of the last fputc() or equivalent that it called. puts() returns EOF (typically -1) on error, or some unspecified non-negative value on success. fputc() returns EOF on error or the written character, treated as an unsigned char and converted to int, on success. Don't expect all puts() implementations to do the same thing. For example, the glibc implementation…

That particular implementation (NetBSD's) (which is transcribed in to the article) does something more optimized than making repeated calls to `putchar()`.

But as pdw's link shows, what you suggest is exactly what the historical implementation was. So NetBSD is simply matching historical Unix.

Re: There is no 'printf'

#45

There is 'printf'. It's just that printf (and the rest of the standard library) is technically as much a part of the C language as the language grammar itself, and C compilers are welcome to use innate knowledge of those functions for optimizations. The other place you typically see this is calls to functions like memcpy/memset being elided to inline vector ops or CISC copies, or on simpler systems, large manual zero…

[deleted]

Re: There is no 'printf'

#46
My compilers call printf just fine until you enable optimizations. -O0 adds references to printf, -O1 and higher switches to puts.

I was kind of surprised about the fact that there was no warning about the missing return from main(). Normally, I'd expect the compiler to complain that a supposed int returning function does not return anything, because that would normally be undefined behaviour.

Re: There is no 'printf'

#47

My compilers call printf just fine until you enable optimizations. -O0 adds references to printf, -O1 and higher switches to puts. I was kind of surprised about the fact that there was no warning about the missing return from main(). Normally, I'd expect the compiler to complain that a supposed int returning function does not return anything, because that would normally be undefined behaviour.

If you use GCC, enable -Wall and you'll get the diagnostic you want:

    /tmp/cp.c: In function 'main':
    /tmp/cp.c:4:1: warning: control reaches end of non-void function [-Wreturn-type]
        4 | }
          | ^
If you use Clang, there is no diagnostic even with -Wall (or even -Weverything), but it looks like Clang always implements the implicit `return 0;` from C99 regardless of the `-std` setting.

Re: There is no 'printf'

#48

My compilers call printf just fine until you enable optimizations. -O0 adds references to printf, -O1 and higher switches to puts. I was kind of surprised about the fact that there was no warning about the missing return from main(). Normally, I'd expect the compiler to complain that a supposed int returning function does not return anything, because that would normally be undefined behaviour.

> I was kind of surprised about the fact that there was no warning about the missing return from main(). Normally, I'd expect the compiler to complain that a supposed int returning function does not return anything, because that would normally be undefined behaviour.

If main() returns without a return statement, it is defined to return 0 by the specification. (§5.1.2.2.3 of http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf, but this hasn't changed in quite some time).

Re: There is no 'printf'

#49

Compiler optimization can sometimes cause unpredictable or even incorrect behavior. Below is a blob of C code for the TI MSP430 compiler that exemplifies at least one of TI's optimization bugs: // Define Common Communications Frame typedef volatile union commFrameType { struct { unsigned SyncHeader:16; unsigned MessageID:8; unsigned short MessageData[msgDataSize]; // ID-unique data unsigned CRC:8; // LSB of CCITT-16…

'unsigned MessageID:8;' isn't the same as 'unsigned char MessageId'

I agree. It's explicitly an unsigned 8-bit integer (bit field). A 'char' can have a different number of bits on different architectures.
Post reply on HN