The first two invoke UB and are thus completely illogical.
They do invoke implementation defined behaviour, but not undefined.
11–20 of 59 posts
The first two invoke UB and are thus completely illogical.
They do invoke implementation defined behaviour, but not undefined.
The first two invoke UB and are thus completely illogical.
I think it's just pointing out the difference between '&' and '&&'.
The first two invoke UB and are thus completely illogical.
To elaborate, the second expression has an underflow at 1 - sizeof(int) on an unsigned integer (promotion due to sizeof being unsigned), which is perfectly well defined:
"if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type."
The right shift is fine on a signed or unsigned integer. For the unsigned case (which is this one due to operator precedence), the behavior is well defined. For signed, implementation defined.
EDIT: The right shift is in fact UB assuming sizeof(int) <= 4.
who said C is simple? :S
The first two invoke UB and are thus completely illogical.
The first invokes UB if you assume that x is a local variable, and the second doesn't at all as far as I can tell. Care to explain? To elaborate, the second expression has an underflow at 1 - sizeof(int) on an unsigned integer (promotion due to sizeof being unsigned), which is perfectly well defined: "if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum val…
I know of three different ways in which platforms implement shifts by greater than the word size.
That meant it was relatively simple to 'see' the assembly language 'behind' a given C function or stretch of code; it didn't take much to get inside the head of a C compiler, so you could be reasonably sure that a simple piece of C would result in a similarly simple piece of assembly out the other end.
That, of course, was well and good when it was reasonably simple to predict actual performance from glancing at assembly code, which assumes opcode performance (as opposed to, say, cache performance) dominates how fast the code runs.
Now... how many of those things still hold true on desktop and server class hardware?