Why can't the C compiler do type inference?

In case, the long double x = 8.99999999999999999

value is saved as double

, since "L" is not added. Why can't the C compiler C inject the output type if I have already declared the variable x

as a float type long double

?

+3


source to share


5 answers


The C compiler does not do type inference because C is not type safe. You can easily discard things that will be invalid, void pointers and back again. It's not against the rules. This implies, at the very least, that any type of C output will only be approximate, and that at best you will have a compiler giving you hints as to what went wrong with your types.

As for why C doesn't do type inference: types in C are not meant to enforce logical relationships or encode truth in a language. At some level, languages ​​with sound systems (Haskell, OCaml, SML, Coq, etc.) assume that types tell you something: there is a theorem that you can write about your program from these types. (See Philip Wadler's “Theorem Free!” Work for an interesting example!)

So why does C use types? The reason is that the compiler needs to know - at some level - how to organize your data as it is stored in memory. Instead of a logical sequence, types in C are meat to tell you how things are laid out, where should I put that int in a struct, etc.



Instead, C has a number of idioms for emulating more standard functions in type-safe languages. For example, void pointers are commonly used to represent parametric polymorphism. (For example, you can have a list that can contain pointers to any data type.) In fact, it does something else, in C you can code lists that point to different data types. While inductive types for lists in traditional functional languages ​​require all elements to be of the same type, you can easily encode types and inersection strings in C (this is done, for example, in C, by marking the elements of a list with an identifier).

There are dialect types with type and memory as an example, see Cyclone , where in some places polymorphism replaces occurrences of things like void pointers while giving you a lot of C language subtleties.

+2


source


The compiler does not do type inference because the HTML standard explicitly states that this should not be done.

Section 6.4.4.2 on floating constants says:

The unused constant is of type double. If the suffix is ​​f or F, it is float. If the suffix is ​​an l or L, it is long double.




Why does the standard say so? Maybe because it simplifies the compiler rather than doing it (to be honest, I don't know for sure).

+4


source


In the early 1970s, when C was first developed, the computer running the compiler was slow with little memory. Because of this, it was necessary to design a language so that the compiler could be simple, so that compilation could be fast. A simple compiler requires the programmer to tell everything, because every time the compiler needs to output it, it uses the processor and memory.

Another, and I think an equally important reason is that people who develop and use C initially write an operating system with it, and they need a language that doesn't try to be smart. Writing operating systems is hard enough without knowing what the compiler might or might not have done: they needed very precise control over what was going on, and a simpler language could be a big advantage for an operating system writer in that sense.

Because of this, C ended up lacking many of the features that higher-level languages ​​developed in the following decades and aimed at programming applications now have. It has no object orientation, no type inference, no garbage collection, no exceptions, and no thread support.

It is possible that in the future C could be changed to have things like this (indeed, the latest C standard has its own streams now, but I believe they are optional), but in general, if you want these things, you need another language. There are literally thousands of interesting languages ​​to choose from.

+4


source


In the case of a long double, x = 3.0. the value 3.0 is stored as double.

Not true! This will store 3.0 as long double

.

+1


source


As stated by other standard states that unless suffixed, a floating point constant is a double

. Now let's look at the rationale behind it from computational complexity. The standard also noted that a long double>=double

Now consider a system where sizeof(double)=8

and sizeof(long double)=16

. Now, in your specific example, which has no suffix, the compiler should simply compute a precision floating point number 64-bit

and zero from the remaining 8 bytes. But if it needs to do type inference as you suppose, it must now do the computation to get the floating point number 128-bit

.

And converting a floating point number to binary is not an easy task and hence the compiler tries to be as mean as possible. Especially in this example, there is no need to update 8.99999999999999999

to long double

as it can be compressed double

with reasonable precision.

+1


source







All Articles