Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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).

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.

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top