In case of long double x = 8.99999999999999999
, the value is stored as double
since ' L ' is not appended. Why can't the C compiler do type inference when I have already declared the variable x
to be a long double
float type?

- 9,558
- 19
- 72
- 111
-
5Because the standard C specification says that it should not do type inference. Look at *Ocaml*, *Haskell* or even *C++11* language specifications for languages with some type inference. – Basile Starynkevitch Apr 06 '12 at 08:08
-
@BasileStarynkevitch: you could put that as an answer. – Kijewski Apr 06 '12 at 08:10
-
What to infer when you have already declared the type ? – Kien Truong Apr 06 '12 at 08:10
-
what is the limiting factor here? Is it a very complicated thing to do? – KawaiKx Apr 06 '12 at 08:11
-
If plain double and long double have different representations, it should be able to directly use the long double representation directly, as the constant value is known. Are you sure this corresponds to the actual problem you are having? – Lindydancer Apr 06 '12 at 08:12
-
You can argue that the compiler inferred the type of the constant; it didn't have an L or F suffix, so it was a `double` constant. It then politely arranged to convert that `double` into a `long double` rather than giving you an error "You can't do that". Pascal compilers don't trust you to know what you're doing; C compilers do trust the programmer. That makes C compilers harder to handle while you don't yet fully understand what you're doing, but is (at least sometimes) a blessing once you do. – Jonathan Leffler Apr 10 '12 at 07:05
5 Answers
In the early 1970s, when the C language was first developed, the computer that would be running the compiler was slow with little memory. Because of this, it was necessary to design the language so that the compiler could be simple, so that compilation could be fast. A simple compiler needs the programmer to tell it everything, because every time the compiler needs to deduce, it uses CPU and memory.
Another, and I think equally important reason, is that the people developing and using C initially were writing an operating system with it, and they wanted a language that did not try to be clever. Writing operating systems is tricky enough without having to guess what the compiler might or might not do: they needed very precise control of what happens, and a simpler language can be a big benefit to the operating system writer in that sense.
Because of these things, C ended up without a lot of features that higher level languages designed in later decades and aimed at application programming now have. It has no object orientation, no type inference, no garbage collection, no exceptions, and no support for threading.
It's possible that in the future C might be changed to have such things (indeed, the latest C standard has native threads now, but I believe they're optional), but on the whole, if you want those things, you want a different language. There's literally thousands of interesting languages out there to choose from.
-
2This is all speculation. All we know is that Dennis Ritchie designed the language that way, based on its BCPL heritage. Another explanation is that Ritchie wasn't really a compiler writer to begin with and hesitated to go where at that time angles feared to tread. – user207421 Apr 06 '12 at 09:40
The compiler does not do type inference because the C standard standard explicitly specifies that this should not be done.
Section 6.4.4.2 on Floating constants 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.
Why does the standard say so? Maybe because it simplifies the compiler, not to have to do it (To be honest, I don't know for sure).

- 23,020
- 5
- 61
- 83
-
1Some C compilers [support extensions](https://stackoverflow.com/a/31709221/975097) for type inference, but they aren't included in the C standard. – Anderson Green Jan 15 '22 at 19:19
The C compiler doesn't do type inference because C is not type safe. You can easily cast things willie nilly to void, void pointers, and back again. It's not against the rules. This implies, at the very least, that any sort of type inference for C would be only approximate, and that at best you'd have the compiler giving you clues as to what went wrong with your types.
As to why C doesn't do type inference: types in C are not intended to enforce logical relationships, or encode truth in the language. At some level, languages with sound type systems (Haskell, OCaml, SML, Coq, etc...) intend that the types tell you something: there's a theorem you can write down about your program from the types. (See Philip Wadler's "Theorem's for Free!" work for an interesting example of this!)
So why does C use types? The reason is purely that the compiler needs to know -- at some level -- how to organize your data as it is stored in memory. Instead of logical consistency, types in C are meat to tell you how things are laid out, where should I put this int within a structure, etc...
Instead, C has a number of idioms to emulate more standard features in type safe languages. For example, void pointers are usually used to represent parametric polymorphism. (So for example, you could have a list which can contain pointers to any data type.) In fact, it does something more, in C you can encode lists which point to different data types. While in traditional functional languages the inductive types for lists require all elements to be of the same type, you can in C easily encode inersection types and rows (this is done, in C, by tagging list elements with an identifier, for example).
There are type and memory safe dialects of C, see Cyclone as an example, where in some places, polymorphism does replace occurrences of things like void pointers while still giving you many of the niceties of the C language.

- 7,572
- 3
- 29
- 34
In case of long double x = 3.0. the value 3.0 is stored as double.
Not true! That will store 3.0 as a long double
.

- 56,922
- 16
- 83
- 148
As others have stated standard states that unless suffixed, a floating point constant is a double
. Now, lets see the rationale behind it from a computational complexity. Standard also noted that a long double>=double
Now consider a system where sizeof(double)=8
and sizeof(long double)=16
. Now in your particular example, which has no suffix, the compiler has to just calculate a 64-bit
precision floating point number and zero off the remaining 8 bytes. But if it were to do type inference as you suggest, it has to now do calculations to yield a 128-bit
floating point number.
And converting a floating point number into binary representation is no easy task and hence compiler tries to be as stingy as possible. Especially in this example there is no need to upgrade 8.99999999999999999
to long double
as it can be squeezed into a double
with reasonable accuracy.

- 27,404
- 12
- 99
- 125
-
About the statement in italics: Not really. #1) I don't see anything in the standard about this. #2) On my copy of GCC, if I assign a huge floating point constant that won't fit into a 'double', to a 'long double' variable, it is printed as 'inf'. Only, as the standard says, if I suffix an 'L' to the constant does it get stored properly into the variable. – ArjunShankar Apr 06 '12 at 09:52
-
@ArjunShankar Did you check whether the sizes of double and long double are same on your system? I am refering to systems where long double is bigger than double? – Pavan Manjunath Apr 06 '12 at 09:54
-
-
@ArjunShankar You are right. I too verified on another system where double was 12 bytes and it did indeed throw an overflow warning. But for me it doesn't show a warning but shows some junk value. gcc 4.6.1. I removed the italicized part anyways – Pavan Manjunath Apr 06 '12 at 10:08