4 ms·
GCC float comparison: since C doesn't have a portable way to denote single precision float constants, it's a good idea to cast them in order to avoid implementa
by vardump 9y ago
GCC float comparison: since C doesn't have a portable way to denote single precision float constants, it's a good idea to cast them in order to avoid implementation specific differences. See: https://godbolt.org/g/t7UYoi https://godbolt.org/g/t7UYoi
int
float_compare(void)
{
float x = 1.3f;
return x == (float) 1.3f;
}
This correctly returns 1 on all compilers I cared to check.
Couldn't reproduce clang calloc removal bug with that code. Tried clang 6.0, -O1, -O3.
Clang did remove calloc when there were no new_image calls where parameter "shade" could be zero. But that's to be expected, as it is a static function, only accessible from same compilation unit. Entirely correct behavior.
https://godbolt.org/g/FfV7G2 https://godbolt.org/g/FfV7G2
When it comes to the filed clang bug, I fail to see any bug at all: https://bugs.llvm.org/show_bug.cgi?id=37304 https://bugs.llvm.org/show_bug.cgi?id=37304
When calloc return value is not stored (or used), how could it be accessed or even freed at all? I think compiler is right to remove whole call.
- unwind 9y agoCan you clarify this part: [...] since C doesn't have a portable way to denote single precision float constants [...] That sounds like the suffix 'f' which you're also using, how is that not a way to "denote single precision float constants"? My draft copy of the C11 spec says: An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has type float. If suffixed by the letter l or L, it has type long double. But this is not new syntax, I just looked in the most recent document I have. Do you mean that C doesn't have a way to require IEEE 754 floating-point?
- vardump 9y agoSee edit below. C99 allows greater precision than required by the type! Hmm, you're right. I think something similar bit me long ago and left me under impression f-suffix for a float is not portable. Perhaps it's time to read the standard through once again... Then again, explicit casts generate code that works on all compilers, standards compliant or not. Edit: C99, 6.3.1.8.2: "The values of floating operands and of the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby." So I guess explicit floating point casts are needed when explicit operations are wanted!
- enqk 9y agoYou might have encountered in the past is C/C++ silently promoting your floats to double. An example, `printf("%f", float_value)` will actually promote float_value to a double. Or calling a function from `math.h` with a float constant
- pubby 9y agoRegarding calloc, the issue is this: - Since C++14, SIZE_MAX is the maximum size of any valid object; any object larger is ill-formed. - calloc(SIZE_MAX, SIZE_MAX) is an attempt at creating an invalid object of size SIZE_MAX^2. - Thus, calloc(SIZE_MAX, SIZE_MAX) should always return null. Shouldn't it? Compilers often remove malloc calls even if the allocated object is modified and freed. But they shouldn't change the program's visible semantics.
- vardump 9y ago> Compilers often remove malloc calls even if the allocated object is modified and freed. But they shouldn't change the program's visible semantics. What visible side effects there are for an allocation with an unused return value pointer (cast to a boolean)? There's no way to reference said memory, so there's no way it can affect execution of the abstract program. If the allocation succeeded, there's no way to free the memory in any case. So even ignoring possible concurrent allocations elsewhere, it's useless for checking whether future malloc can succeed. Unless, of course, I missed something obvious.
- dooglius 9y ago> When calloc return value is not stored (or used), how could it be accessed or even freed at all? I think compiler is right to remove whole call. The calloc return value _is_ used, to calculate the return value.