Live data from Hacker News

Const and Optimization in C

nullprogram.com

11–20 of 44 posts

Re: Const and Optimization in C

#11
post #9
post #8

Earlier quoted context omitted.

"casting away const-ness is undefined" No, it's not. That's the whole point why compiler can't optimize it away. You can often see ("char *") casts from static "strings" in legacy APIs and libraries calls, because original authors didn't know or didn't care how to use const correctly (or at all). I, personally, use const a lot throughout my C code, when you get it, it makes debugging so much easier.

you skipped the first clause of my sentence -- if a variable is declared const, casting away const-ness is undefined is that not true?

The cast itself is not undefined.

It's completely valid to use a non-const pointer to a const variable for reading that variable (this is actually quite common when interacting with libraries that are not const-correct). Undefined behavior only occurs when the const variable is being modified.

Re: Const and Optimization in C

#12
post #9
post #8

Earlier quoted context omitted.

"casting away const-ness is undefined" No, it's not. That's the whole point why compiler can't optimize it away. You can often see ("char *") casts from static "strings" in legacy APIs and libraries calls, because original authors didn't know or didn't care how to use const correctly (or at all). I, personally, use const a lot throughout my C code, when you get it, it makes debugging so much easier.

you skipped the first clause of my sentence -- if a variable is declared const, casting away const-ness is undefined is that not true?

To reinforce the sibling comment's point: A very common pattern is when a const variable resides in non-writable memory (happens all the time in embedded), - if you attempt to write to it, you trigger a fault.

So if you cast away constness to conform to some API and then read the value, everything is fine (aside from questionable API design, of course). Modifying the value is another story, though.

Re: Const and Optimization in C

#14
post #10
post #7

The C99 specification, in §6.7.3¶5, has one sentence just for this: If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non- const-qualified type, the behavior is undefined. This is a separate question than whether the compiler can rely on the function prototype, but doesn't his definition of bar() invoke undefined behavior by this rule? void foo(const int *read…

`readonly_x` is a non-constant object of type 'pointer to const int'. If `readonly_x` itself was const-qualified, it'd look like this: `const int* const readonly_x`. This is a distinct object from whatever pointer the caller is passing in. But none of this matters to the special const rule -- that rule is not talking about the pointer object, but about the target object that the pointer is pointing to.

Thanks, that goes a long way toward an explanation. I'm still a bit surprised though that no compilers seem to complain even if we cast away the const from the properly const-qualified version. Here's the snippet I was playing with that tests all the variations: https://godbolt.org/g/aaC4B7

I should have expected it, but if you define the "lying" function where the compiler can see the full definition (and don't specify -fno-inline), the loads are optimized out. It made me wonder though whether some variation of this bug might apply : http://www.playingwithpointers.com/ipo-and-derefinement.html

Re: Const and Optimization in C

#15
post #9
post #8

Earlier quoted context omitted.

"casting away const-ness is undefined" No, it's not. That's the whole point why compiler can't optimize it away. You can often see ("char *") casts from static "strings" in legacy APIs and libraries calls, because original authors didn't know or didn't care how to use const correctly (or at all). I, personally, use const a lot throughout my C code, when you get it, it makes debugging so much easier.

you skipped the first clause of my sentence -- if a variable is declared const, casting away const-ness is undefined is that not true?

Yes, if a variable is declared const, casting away const-ness from a pointer to it and then writing to it is undefined.

Re: Const and Optimization in C

#16
post #9
post #8

Earlier quoted context omitted.

"casting away const-ness is undefined" No, it's not. That's the whole point why compiler can't optimize it away. You can often see ("char *") casts from static "strings" in legacy APIs and libraries calls, because original authors didn't know or didn't care how to use const correctly (or at all). I, personally, use const a lot throughout my C code, when you get it, it makes debugging so much easier.

you skipped the first clause of my sentence -- if a variable is declared const, casting away const-ness is undefined is that not true?

I think it is only modifying that non-const value that is undefined. If you use a nominally mutable value in a read-only way, then you are OK.

This is important because older libs that ignore (or abuse) const will often do read-only access to a char* or something. A nice example is that POSIX defines

    int execv(const char *path, char *const argv[]);
That definition takes a constant pointer to variable chars! Worse, some people use the same signature for `main()` and also for libraries that parse `argv`. But none of them are actually allowed to vary those chars under Unix.

Re: Const and Optimization in C

#17
post #13

One of the subtler distinctions between C and D is D does allow this optimization. This occasionally engenders debate about which is better.

What is the argument in favor of specifically allowing casting away const of pointers?

The strongest argument is to support a sort of poor man's const-generics. Consider a function like strchr(). This locates a character in a (const) string, and returns a (non-const) pointer to it.

The idea is that you can use this on both const and non-const strings. Call it on a const string, you get back a non-const pointer (which you better treat as const!) But call it on a non-const string, you get back a non-const pointer, with which you can mutate the string. So a single function serves both const and non-const uses.

If casting away const-ness were disallowed, the compiler might conclude that strchr()'s returned value cannot alias the input string, and its optimizations would defeat this design. Anyways that's the original rationale.

Re: Const and Optimization in C

#18
post #13

One of the subtler distinctions between C and D is D does allow this optimization. This occasionally engenders debate about which is better.

What is the argument in favor of specifically allowing casting away const of pointers?

Logical const and expressiveness.

Re: Const and Optimization in C

#19
post #13

One of the subtler distinctions between C and D is D does allow this optimization. This occasionally engenders debate about which is better.

What is the argument in favor of specifically allowing casting away const of pointers?

- In some case implementing both "const" and "non const" methods cause a lot of code duplications and cast can help.

- Compatibility with old libraries

Post reply on HN