Liste des Groupes | Revenir à l c |
Michael S <already5chosen@yahoo.com> writes:I am in two minds about this. I think there are good reasons for wanting compatibility between different integer types of the same size. But I prefer stronger separation between user-defined types - structs in C.
On Fri, 11 Apr 2025 17:22:37 -0000 (UTC)
Kaz Kylheku <643-408-1753@kylheku.com> wrote:
>On 2025-04-11, Michael S <already5chosen@yahoo.com> wrote:>
>On Thu, 10 Apr 2025 17:59:15 -0700>
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>An understanding of what "compatible types" means.>
Bart didn't say that types are compatible or non-compatible.
He said that they are 'compatible enough'. That is not terminology
of C Standard, but terminology of his own. And he seems to
understand it.
>
In my own translation, 'compatible enough' means that when these
structs are accessed then any sane or even semi-sane compiler will
generate code that will have the same effect as in case of access
through structures with literally identical declarations.
so struct { long x; } and struct { int x; } are compatible enough,
in situations that are portable enough.
I wish they would be, but according to C Standard they are not,
ene when both represent 32-bt signed integer. That's because of
misfeature called 'strong aliasing rules'.
IMO, C would become better without this misfeature.
I think this reaction is rather shortsighted. Making this changeThe semantics I would recommend are extremely simple - arithmetic types which have identical sizes, values, and representations, should be compatible.
would incur several downsides, and offers no significant upside
that I can see.
First it would greatly complicate the language semantics.
Whether a program is meaningful, and if so what the meaning is,
would be much harder to state than it is now.
Second it would imply that whether a program is well-defined is aIt would make some programs that are currently incorrect, correct. And yes, it would mean that if code mixes up types and pointers, code may not then be portable - for example, code that passed the address of an "int" to a function requesting a "pointer to long" would compile on 64-bit Windows and not on 64-bit Linux. But a lot of code is already non-portable, and I do not think this suggestion would make the situation significantly different.
lot more dependent on implementation-specific choices than it is
now.
Third, as a consequence of that, it would be harder to writeI cannot see a basis for that. Compilers and other code analysis and verification tools can add whatever extra checks and controls they want. And I suspect it will be easier to check that code is correct according to the suggested updated rules than to spot some kinds of subtle mistakes using the existing rules.
program verification tools, because they would need to take these
more extensive implementation dependencies into consideration.
Fourth, there would be consequences for program optimization, andIt is certainly the case that there are some optimisation opportunities due to the "strict aliasing" rules - the compiler knows that an "int *" pointer and a "long *" pointer do not point to the same data even if "int" and "long" are the same size on that platform. Analysis (I have read reports on this, but do not have references for them) of code generation by compilers with "strict aliasing" optimisation has, however, shown that it is rare that such optimisations make much difference - and often you would much better results from using "restrict". Also, with my suggested changes, compilers would retain the knowledge of no aliasing between integer types and floating point types, or between struct types.
it is hard to dismiss those. Some people may not care about the
optimizations losses, but certainly many people want the benefits
of those optimizations.
Fifth, related to the previous point, as a practical matter it wouldAlmost anyone interested in serious optimisation is already going to be using non-portable and compiler or target specific features. That objection is a complete non-issue.
make getting the optimization benefits back again be nearly
impossible. As things are now, it's easy to have a compiler option
to disable the consequences of strong typing rules, and the result
can still be a conforming implementation. But if the C standard
would prescribe the semantics of cross-type access, then any option
to ignore the implications of that prescription would necessarily
make using said option result in a non-conforming implementation.
To say the last point another way, with things as they are nowI have now made a case for a limited change to the aliasing rules (whether the change is made by type compatibility rules, constraints on assignment, or "effective type" rules). I did not think it was particularly hard to do so.
developers can choose whether they want to observe the cross-type
access restrictions, or ignore them, and still get a C compiler.
If the effective type rules were discarded, there is no way to
choose the more-optimizing path without getting something that
is not a C compiler.
Given that you can always get what you want either by choosing
an appropriate compiler option (if available) or by using one of
the well-known legal workarounds, I think it's hard to make a
case that getting rid of the effective type restrictions is a
good idea.
Les messages affichés proviennent d'usenet.