Page 3 of 6

Re: C and undefined behavior

Posted: Thu Jun 10, 2021 7:39 am
by vvaltchev
Solar wrote:Thought experiment. Let's say the next generation of the architecture changes that behavior. Let's say the next x86 to appear adds different opcodes for ADD / MULT that trip on signed integer overflow, to finally get rid of all the pesky little programming mistakes.

From my POV, compiler manufacturers would be perfectly fine to make use of that new ADD/MULT. From your POV, they would not. That is what it boils down to.
More or less, yes.
Solar wrote:You want freedom to be lazy. Compiler manufacturers want freedom to produce more efficient code.
The second part is totally correct. The first is not. I want determinism and simple and well-defined behavior in many more cases. In particular when I'm writing those small parts of per-architecture code inside a kernel that cannot by definition be ported. Obviously, the perspective of userspace developers is different and most (99.9%) of C and C++ code in the world is definitively not in kernel, so it's better be portable. So, it's not about laziness at all. Actually, because I'm well aware of UB and not lazy I am particularly careful and obsessed with avoiding it in my own projects. I have plenty of tests and I compile the project with both clang and gcc in a variety of configurations. All optimization levels are support from -O0 to -O3, from the very beginning. I use sanitizers like UBSAN as well. I am do my best to write 100% UB-free code. So, you simply cannot accuse me of laziness. I have a different perspective about software trade-offs than yours. That's it.
Solar wrote:
vvaltchev wrote:...unless I ask for it with an option like -fforce-alignment or something like that. Or at least, make alignment requirements default (because the ISO doc) but support an option like -fno-strict-alignment or -fallow-non-portable-features. Something like that.
Well, they do the second. That's where you cross from strictly conforming to compiler-specific code.
Yes, the do, sometimes. In other cases, they just don't care.
Solar wrote:That sounds quite different from your initial statement in this thread, which was mostly about how other people misinterpreted the "true vision" of C.
Yes, simply because I went off-topic in my own thread, just to share more of my views. Otherwise, to be back on the topic, I agree with Eskil Steenberg's thesis. Obviously you don't and that's fine too. I wanted to see as many opinions as possible, instead of "fighting" with single individuals.
Solar wrote:It also puts on the table what you, and those blog writers, could do: Attend the committee meetings. Most of the compiler manufacturers are right there. You can present your reasoning, and they will consider what you have to say. They might even agree and make changes, but as you have seen in this thread, I personally would not hold my breath for it.
I have no interest in that, at the moment, because I honestly believe I don't stand a chance. I deeply understand their perspective and their goals. It won't make much sense for them to turn back 180 degree, no matter what I say. They simply have chosen a different set of trade-offs.
Solar wrote:I dislike this "rolling the drum to sway public opinion" approach, especially when the issue at question is decided by a committee vote, not a public vote. It basically serves no purpose, other than perhaps vent your feelings. It can also be quite damaging, even though I don't think something as well-established as C will care either way.
I can see that. You dislike people freely sharing their opinion about technology. Also, you're wrong about the public vote. People "vote" implicitly every time they use a technology. People's vote is almost all the matters. A committee has no chance at physically imposing anything on anyone. They just end up with an official piece of paper. How much that really matters, depends on willing of the people. It's simple as that.
Solar wrote:
vvaltchev wrote:An ISO document shouldn't be treated like a gospel. At some point, it could be replaced by a different one if enough people are not OK with it.
That is my point: Neither you nor me are on the committee. Our opinions quite plainly do not matter in this regard. Even addressing your compiler manufacturer of choice will likely only change that compiler's implementation-defined behavior if you are lucky.
Our opinions do not matter to the committee, but they might to other developers. It's simple as that.
Solar wrote:This is not intended to turn your opinions down.
Nice to hear that, man. I had the impression that such an opinion as mine does not even deserve to exist in your POV. While, note: I believe that my "opposite" opinion, the one shared by you and the committee is meaningful and has its good purpose to exist. I deeply respect opinions that differ with mine.
Solar wrote:This is encouragement to take your opinion up with the committee. They are actually quite open about it. Erin Shepherd filed a paper with the committee for shortcomings of the way threads are defined in C11 she came across while working on PDCLib, and they duly discussed it.
Well.. thanks for that. Just, as you probably noticed, I'm not the most convincing guy out there, nor the most qualified in terms of expertise in computer languages etc. Mine is just a humble opinion from the POV of a kernel developer.
Solar wrote:Wait, did we just come full circle on this? Yes, I think we did. :twisted:
Yeah, man. I think we exhausted all of our points. It would be great to hear other people's opinion too, if anybody else is willing to share :-)

Re: C and undefined behavior

Posted: Thu Jun 10, 2021 8:05 am
by Solar
vvaltchev wrote:
solar wrote:From my POV, compiler manufacturers would be perfectly fine to make use of that new ADD/MULT. From your POV, they would not. That is what it boils down to.
More or less, yes.
Doesn't that limit what you can to with the compiler, instead of widen it? There is an extension to the ISA, a beneficial one that could avoid a lot of otherwise silent errors. But you cannot make use of it because past code is broken?

vvaltchev wrote:
Solar wrote:Well, they do the second. That's where you cross from strictly conforming to compiler-specific code.
Yes, the do, sometimes. In other cases, they just don't care.
Because the benefits of compiler-specific code are limited, and people are generally trying to move away from that, because C is and was intended as a kind of portable assembler. Compiler specifics aren't.
vvaltchev wrote:I deeply understand their perspective and their goals. It won't make much sense for them to turn back 180 degree, no matter what I say. They simply have chosen a different set of trade-offs.
That's fine. But...
vvaltchev wrote:I can see that. You dislike people freely sharing their opinion about technology.
I dislike people putting up an argument for argument's sake. One paragraph above you said that you don't believe anything you do will sway the committee. So now you're about trying to make people angry with the committee. (Mark you, without even having taken the effort to hear them out.)
vvaltchev wrote:Also, you're wrong about the public vote. People "vote" implicitly every time they use a technology. People's vote is almost all the matters. A committee has no chance at physically imposing anything on anyone. They just end up with an official piece of paper. How much that really matters, depends on willing of the people. It's simple as that.
I don't think you have understood who is on the committee, and how they work. I happened to have a co-worker who actively participates in the C++ committee, so I allow myself to believe I have somewhat of an insight: This isn't a top-down force feeding they do. They take feedback all the time, and they are quite careful about where they steer that ship they have been given to man. There's compiler manufacturers and library implementors there, as well as some big-name software developers, professional tutors, and what remains of the "founding fathers"...
vvaltchev wrote:Our opinions do not matter to the committee, but they might to other developers. It's simple as that.
So you're trying to mount a revolt because the vote taken in the committee (in which you might participate!) doesn't appeal to you?

A couple of paragraphs up you accused me of being antidemocratic... 8)
vvaltchev wrote: had the impression that such an opinion as mine does not even deserve to exist in your POV.
"Deserve to exist" are hard words I usually reserve for nazis, racists and the like. I just think your view on the matter is deeply flawed, and that setting it right might help you going forward.
vvaltchev wrote:Yeah, man. I think we exhausted all of our points. It would be great to hear other people's opinion too, if anybody else is willing to share :-)
I found our conversation here to be quite engaging. Sorry if you took offense at what I said.

Re: C and undefined behavior

Posted: Thu Jun 10, 2021 8:23 am
by vvaltchev
Solar wrote:Now that we apparently exchanged our POV's on the philosophical side of things, let us not ignore the technical:

Those guys you quote are using really, really bad examples, because at the end of the day, you will actually get what you want.

Let's take that GCC "bug" as an example.

Code: Select all

assert( x + 100 > x );
Consider the following:
  • The statement "x + 100 > x" has no side effect.
  • Unless you consider platform-specific behavior (i.e., signed integer overflow), the statement "x + 100 > x" must evaluate to "true".
  • By the same token, unless you consider platform-specific behavior, the statement "assert( x + 100 > x )" is a no-op.
  • According to the "as-if" rule, statements that have no observable effect may be optimized away.
Optimization happens before executable code is generated. Making the optimization step of a cross-platform compiler aware of all kinds of platform-specific behavior adds a lot of switches and additional logic.

So it is not as simple as claiming that "of course" the optimizer stage needs to be aware that, on the given target platform (which might be different from the compilation platform!), the above statement might evaluate to something other than "true".

What we are looking at here is not some sophisticated corner-cutting by the compiler! It is quite the opposite, the compiler making the simple assumption.


I agree with everything you said in here from the technical point of view. There's nothing I didn't already knew about that example. On the non-technical side I have mixed feelings. I'm so excited about compilers optimizing as much as possible, like no-op expressions like in this case, that I'm not sure what I really I know what I want to happen here, in general. If there was an actual lvalue that gets incremented, probably I'd want to wrap around (or whatever) deterministically and not being optimized away but, again, technically lvalues can be optimized away too and I wouldn't want to give up on that so... it really depends on the code I'm writing. For general average or high-level code, I'm think I prefer the modern behavior. For low-level code (which is a small part of a project) I guess I prefer the compiler to do exactly as I said. It's complicated and it all depends on the context.

Again, I mentioned that bug as a data-point in the timeline of C's history. The guy had a point, but that doesn't mean I fully agree with his view. I've written both very low-level code and very high level code in my career. I don't want to apply the same rule for everything.

Let me share something more about me that could surprise you. I'm generally good at guessing to what extent I can write "do as I mean" code and get it all optimized. I'm very used with that, as I've been working professional as a C++ engineer for many years. I'm used to rely of multiple levels of inlining and/or partial inlining, C++ template meta-programming machinery and all of that. I've written hundreds of lines of such code that get compiled to down to few instructions and I even liked doing that. My opinions about C and UB are from the kernel development POV, the kind of development I'm doing now. The "low level" mindset is necessarily different than the "high level" one because of the kind of problems we're facing.

Unfortunately, when we talk with "people online" we know nothing about their background, never worked with them and sometimes assume the worst.
Solar wrote:Right now I unfortunately don't have access to my "old ladies" at home. As soon as I get back, I'll check the above code on some pre-89 compiler, and I am pretty sure the above code will get optimized away...
It would be nice to see what happens with that compiler.

Re: C and undefined behavior

Posted: Thu Jun 10, 2021 8:58 am
by vvaltchev
Solar wrote:Because the benefits of compiler-specific code are limited, and people are generally trying to move away from that, because C is and was intended as a kind of portable assembler. Compiler specifics aren't.
Well, I agree that C was intended to be a portable assembler but, what is now doesn't match up with my definition of "portable assembler". I'd define modern C as an abstract compiled language.
Solar wrote:I dislike people putting up an argument for argument's sake. One paragraph above you said that you don't believe anything you do will sway the committee. So now you're about trying to make people angry with the committee. (Mark you, without even having taken the effort to hear them out.)
It's so hard to make you understand what I mean. It feels like communicating from different planets. The committee doesn't really care so much about the "kernel" corner case. Actually, the "C" committee almost doesn't not exist. It's almost a sub-committee of the C++ one, the one that has real funding etc. Many things that pass in the C++ standard get "cross-ported" to the C one.
Solar wrote:I don't think you have understood who is on the committee, and how they work. I happened to have a co-worker who actively participates in the C++ committee, so I allow myself to believe I have somewhat of an insight: This isn't a top-down force feeding they do. They take feedback all the time, and they are quite careful about where they steer that ship they have been given to man. There's compiler manufacturers and library implementors there, as well as some big-name software developers, professional tutors, and what remains of the "founding fathers"...
I know all of that pretty well. I had colleagues involved there too. Please, don't assume the worst when I say something that doesn't make much sense to you. The point is they target general C++ software and maintain the ISO C almost as a side-effect.
Solar wrote:
vvaltchev wrote:Our opinions do not matter to the committee, but they might to other developers. It's simple as that.
So you're trying to mount a revolt because the vote taken in the committee (in which you might participate!) doesn't appeal to you?

A couple of paragraphs up you accused me of being antidemocratic... 8)
You're exceptionally good at interpreting my statements against me. I have to admit, I am impressed. Look, if most of the committee members cares about "general software" and not so much about "kernel", so there's no chance things to change with a vote. And, even if some point can be made about new code targeting embedded software etc., legacy C code doesn't stand a chance, if particular once they can prove it wrong on the paper. We have much more chances at convincing compilers to change behavior with ad-hoc options etc. than to change anything in the ISO standard.

But, in reality, I never wanted to convince anybody about anything. Let's not even mention absurdities as "mounting a revolt". I just wanted to see how many people here, in this community, agree with such views about the history of C and UB. I have no idea how the whole thing derailed to this point.
Solar wrote:I found our conversation here to be quite engaging. Sorry if you took offense at what I said.
Well, it started to feel better in the latest comments. At the beginning, I felt "violently" attacked. I had to fight to show that I'm not an idiot, but I just have an unpopular opinion. And you know what's the best? I'm great at making both the sides to hate me. Your "side" (let me brutally simplify things for the sake of the joke) don't like me because I look like too much as an "outlaw cowboy" who doesn't care (nor understands) the great rules of "the language". The other side, Linux kernel developers, don't like me because I'm in their view, a pedantic language lawyer obsessed with UB. Check this e-mail I've sent to LKML: https://lkml.org/lkml/2021/5/4/558.

So, I'm right in the middle: criticizing the ISO standard, but trying to follow it as much as possible. And.. everybody hates me :D

Re: C and undefined behavior

Posted: Thu Jun 10, 2021 12:01 pm
by mid
For the record, I very much agree. This feels like competition that ramped up to the point of screwing over the rest of us, i.e. not different from the rest of the world. In the end, C ends up being great for nothing.

Re: C and undefined behavior

Posted: Thu Jun 10, 2021 1:19 pm
by Solar
And that is exactly the kind of baseless, pointless doom & gloom that I was referring to when I talked about my dislike for "rolling the drum" like this. People start repeating slogans without actually thinking, because "the world is bad".

That's a mindset that only very unsavory people actually benefit from.

I challenge you: Show me some ability to do something, which you actually need, which modern C compilers have taken away from you.

Re: C and undefined behavior

Posted: Thu Jun 10, 2021 5:47 pm
by vvaltchev
Solar wrote:And that is exactly the kind of baseless, pointless doom & gloom that I was referring to when I talked about my dislike for "rolling the drum" like this. People start repeating slogans without actually thinking, because "the world is bad".
I understand what you mean, but how do you know that people don’t think? Maybe this whole discussion actually made several people think for themselves and take a rational position. Hearing both the sides of a story is the only fair approach. Following your analogy, the world is not bad, but not good either. Modern C is not, in absolute terms, better or worse than “old C”. It’s different. Certainly more portable, certainly easier to optimize, but also less intuitive, more distant from the hardware and with many more traps and pitfalls. Modern C is much more predictable across different targets than old C, but less predictable on a specific given target. Obviously, I’m implying here a large codebase with an undefined amount of UB. UB free code is harder to write if you need to do low level stuff, but if you can actually be sure that your code is UB-free (and that’s not trivial to prove) modern C and its compilers are better than older ones, of course.
Solar wrote: I challenge you: Show me some ability to do something, which you actually need, which modern C compilers have taken away from you.
The ability to compile and run reliably non-portable legacy code, written under different assumptions by experts with #ifdefs etc. That’s a pretty valid point, from my POV.

But, if we exclude that case because the interpretation of the “law” is above anything else and we consider all of that legacy code as broken, there’s nothing, at the moment, that has taken away from me in terms of features. Just, some things that in the past were easy and intuitive to do, now require extra carefulness and non intuitive solutions. For example, using __builtin_memcpy() for unaligned access, even on targets where that’s completely safe. But, I’m totally fine with paying this price for the sake of performance and portability. Unfortunately, when I don’t need portability, I have no choice but to continue paying the same price.

Still, I repeat, it’s not the end of the world. Just, I believe it’s not what C was in the eyes of its creators, for good or for bad. I might not have convinced you about the different meaning of UB in C89, but from your comments I deducted that you agreed that Dennis Ritchie wasn’t in favor of anything close to the modern UB. Why it matters? Well, maybe it doesn’t matter for any practical purposes today, but it’s good to know the history of things. It’s like knowing where a given word comes from and why we use it today like that.

Re: C and undefined behavior

Posted: Sat Jun 12, 2021 11:39 am
by vvaltchev
Solar wrote:
vvaltchev wrote:
solar wrote:From my POV, compiler manufacturers would be perfectly fine to make use of that new ADD/MULT. From your POV, they would not. That is what it boils down to.
More or less, yes.
Doesn't that limit what you can to with the compiler, instead of widen it? There is an extension to the ISA, a beneficial one that could avoid a lot of otherwise silent errors. But you cannot make use of it because past code is broken?
I'd like to add here that it happens ALL THE TIME that CPU manufacturers introduce new instructions and we most of the time cannot allow the compiler to take advantage of them, because our binary won't run on older CPUs. For example, when we compile for x86_64, it doesn't mean we can benefit from instructions available in Skylake. For most of the software, "x86_64" means the original baseline micro-architecture, certainly not x86_64-v4. To take advantage of all the new instructions, we have to target a specific generation e.g. Skylake and lose compatibility with older CPUs or execute CPUID and take a runtime decision, but for that we need to compile at least part of our code for both for the new and the old CPUs. In other words, we'd need something like a "fat binary" or to emulate it manually. For example, I know that in glibc CPUID is used to select at the runtime the best memcpy() implementation etc.

Also, if your new instructions trap instead of wrap-around, the OS have to support that too in order to everything to work correctly. Usermode is pretty limited. So, not only our users would need a newer CPU, but they would need an updated OS too, in order to benefit from the new feature. In other words, even if it's possible, it's not so easy to support such a new behavior. It's very unlikely that developers, for most of the projects, would spend effort to support such kind of new instructions, unless there's an incredible performance benefit. Again, when we compile for x86_64 without the -march option, I believe on most of the Linux distros, we're still targeting the original x84_64, with SSE2 at most. So, even if auto-vectorization is enabled and we're running on the super-modern machine with AVX2, the compiler will still use, by default, at most SSE2 instructions. And there are many benefits for using the latest instructions, just it's not worth the effort for most of the software. Of course, for things like libffmpeg, glibc etc. it's different, but that fits in 1% of the cases and requires extra effort to support both the new and the old CPUs.

Re: C and undefined behavior

Posted: Sat Jun 12, 2021 4:43 pm
by Korona
vvaltchev wrote:Did Fortran (a language I never learned) had any form of pointers back then (before 1990)? If it didn't, we cannot talk about aliasing rules since the language didn't have the basic tool for introducing any kind of aliasing. If it did, how did it work? Like in modern C with UB in case of aliasing? Can you show me some examples? How programmers checked for UB? I'd be super interested in understanding that with real examples.
Yes, Fortran already had data types equivalent to pointers before, and yes, Fortran behaves like "modern C with UB" w.r.t. aliasing. Arrays of the same type never alias in Fortran, so if you have the equivalent of a foo(int *x, int *y) function and you pass the same arrays as x and as y, compilers (even old ones) will generate garbage code. They will not make a best-effort to replicate what the programmer wrote in assembly, they will just assume that aliasing doesn't happen. In particular, if you do the equivalent of "x[0] = 5; y[0] = 7; return x[0];" you will most likely get 5 and not 7 (and further optimizations will be based on this behavior, so it propagates through the program just like in the case of modern C compilers).

Re: C and undefined behavior

Posted: Sun Jun 13, 2021 8:36 am
by vvaltchev
Korona wrote:Yes, Fortran already had data types equivalent to pointers before, and yes, Fortran behaves like "modern C with UB" w.r.t. aliasing. Arrays of the same type never alias in Fortran, so if you have the equivalent of a foo(int *x, int *y) function and you pass the same arrays as x and as y, compilers (even old ones) will generate garbage code. They will not make a best-effort to replicate what the programmer wrote in assembly, they will just assume that aliasing doesn't happen. In particular, if you do the equivalent of "x[0] = 5; y[0] = 7; return x[0];" you will most likely get 5 and not 7 (and further optimizations will be based on this behavior, so it propagates through the program just like in the case of modern C compilers).
Thanks for continuing this conversation, you're making a very interesting point here. So, if I've understood correctly, you're saying that at the time C89 became a standard, the mainstream compiled language Fortran, already have a UB similar (at least in substance) to what we have today with C.

That makes me curious about two things:

- Did most of the Fortran programmers at the time knew and fully understood UB? In other words, was most of Fortran code written at the time UB-safe?

- If C89 intended UB like Fortran did, which is totally possible given the Fortran example, why most (if not all) the C compilers at the time didn't treat UB like Fortran compilers did? Obviously, I'm not talking about aliasing limitations which really were introduced in C99 with "restrict" etc., but about UB in general? Given the evidence in the legacy C source code, it looks like most of the people didn't write UB-safe code. Most projects used to be made of non-portable C code with #ifdefs to make it portable. Why such a distorted culture existed among C developers, while, apparently didn't exist among Fortran ones? If the answer is "because C compilers didn't treat UB like today", I'd say: "and why was that the case, giving the Fortran example?"

It looks to me that C was really different than Fortran in its inception and gradually adopted some of its ideas, in order to benefit from more optimizations.

Look what I've found on wikipedia about UB: https://en.wikipedia.org/wiki/Undefined_behavior
Wikipedia wrote: In the early versions of C, undefined behavior's primary advantage was the production of performant compilers for a wide variety of machines: a specific construct could be mapped to a machine-specific feature, and the compiler did not have to generate additional code for the runtime to adapt the side effects to match semantics imposed by the language. The program source code was written with prior knowledge of the specific compiler and of the platforms that it would support.

However, progressive standardization of the platforms has made this less of an advantage, especially in newer versions of C. Now, the cases for undefined behavior typically represent unambiguous bugs in the code, for example indexing an array outside of its bounds. By definition, the runtime can assume that undefined behavior never happens; therefore, some invalid conditions do not need to be checked against.
Even according to Wikipedia in the "early versions of C" UB was used with a different purpose.

Re: C and undefined behavior

Posted: Sun Jun 13, 2021 10:22 am
by Korona
vvaltchev wrote:Given the evidence in the legacy C source code, it looks like most of the people didn't write UB-safe code.
Do you have any evidence for the quote above?

I've seen plenty of legacy C code bases (just look at bash -- which is written in K&R C to this day -- or BSD kernels that have been written in the 1980s) and I don't think that this is really true. Yes, programs that have been written before ANSI C was standardized might need to pass -fno-strict-aliasing, but other than that, they took care to avoid UB just like we do today. Even compilers used in the 1980s (such as the one developed by Andrew Tanenbaum for MINIX) performed optimizations that relied on the compiler being able to infer that the value of a variable cannot be changed through certain pointers (and for example, the paper mentions that the compiler will produce garbage if the programmer uses setjmp incorrectly).

I think this whole "UB meant something else in the past" argument just has no basis if you look at the history.

Re: C and undefined behavior

Posted: Sun Jun 13, 2021 11:41 am
by alexfru
vvaltchev wrote:I'm not talking about aliasing limitations which really were introduced in C99 with "restrict" etc.
Um... How about this?:
ANSI C wrote: 3.3 EXPRESSIONS
...
An object shall have its stored value accessed only by an lvalue
that has one of the following types: /28/

* the declared type of the object,

* a qualified version of the declared type of the object,

* a type that is the signed or unsigned type corresponding to the
declared type of the object,

* a type that is the signed or unsigned type corresponding to a
qualified version of the declared type of the object,

* an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a
subaggregate or contained union), or

* a character type.
No restrict yet, no explicit use of the word alias either.

Re: C and undefined behavior

Posted: Sun Jun 13, 2021 12:01 pm
by vvaltchev
alexfru wrote:No restrict yet, no explicit use of the word alias either.
I'm sorry, I didn't get your point. Of course no "restrict" nor "alias" in ANSI C, that's what I said: they have been introduced in C99. I don't understand what you wanted to say in your comment.

Re: C and undefined behavior

Posted: Sun Jun 13, 2021 12:13 pm
by alexfru
vvaltchev wrote:
alexfru wrote:No restrict yet, no explicit use of the word alias either.
I'm sorry, I didn't get your point. Of course no "restrict" nor "alias" in ANSI C, that's what I said: they have been introduced in C99. I don't understand what you wanted to say in your comment.
What I quoted are the earliest aliasing rules standardized in C. You seem to suggest they appeared in C99, but they were there in C89 already.

Re: C and undefined behavior

Posted: Sun Jun 13, 2021 12:25 pm
by vvaltchev
alexfru wrote:
vvaltchev wrote:
alexfru wrote:No restrict yet, no explicit use of the word alias either.
I'm sorry, I didn't get your point. Of course no "restrict" nor "alias" in ANSI C, that's what I said: they have been introduced in C99. I don't understand what you wanted to say in your comment.
What I quoted are the earliest aliasing rules standardized in C. You seem to suggest they appeared in C99, but they were there in C89 already.
You quoted this:
ANSI C wrote: 3.3 EXPRESSIONS
...
An object shall have its stored value accessed only by an lvalue
that has one of the following types: /28/

* the declared type of the object,

* a qualified version of the declared type of the object,

* a type that is the signed or unsigned type corresponding to the
declared type of the object,

* a type that is the signed or unsigned type corresponding to a
qualified version of the declared type of the object,

* an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a
subaggregate or contained union), or

* a character type.
Which does NOT contain the word "restrict" nor the word "alias" and you said:
alexfru wrote:No restrict yet, no explicit use of the word alias either.
Which is correct, but it's exactly what I said.
alexfru wrote:but they were there in C89 already
YOU quoted something from ANSI C and YOU stated that:
alexfru wrote:No restrict yet, no explicit use of the word alias either.
It appears that you don't agree with your own comments. Maybe you copy-pasted the wrong text?