283 comments

[ 3.0 ms ] story [ 263 ms ] thread
I sometimes wonder what the world of computing, or even the world in general, would look like today if Linus Torvalds hadn't existed, or happened to have not gotten into computers.
Someone else would have.
(BSD :-))
Theo de Raadt has this potential on the alternative timeline.
They very well may have, but is there any compelling evidence that leads one to such a conclusion? (Or, were you referring to the purchase of GitHub...in which case, ignore my comment.)
Better security in general maybe? The mainline kernel community is known for its conservatism on introducing security mitigation that may affect development in other ways. In comparison, BSD is more security-minded (M* Money per Linus). Although much has been changed after KSPP.
Except BSD even being older than Linux never really took off either in Desktop space or Servers.
Thanks AT&T suit and the MIT licensing, lots of companies use BSD derived OSes without giving anything back.

Linux only took off thanks to SGI, IBM, HP, Cray seeing value reducing costs from their own in-house systems to something else.

Agree with your points about the suit and Licensing.

> Linux only took off thanks to SGI, IBM, HP, Cray seeing value reducing costs from their own in-house systems to something else.

This seems unfair, Linux took off because it constantly kept getting improved and has more and more developers contributing to it. It didn't only take off because it was cheap, but it kept on improving. Also, the Elitist mindsets of some BSD devs and community go back to harm it. Try contributing to OpenBSD or FreeBSD and compare it with how approachable and relatively easy it is to contribute to Linux is.

Also, it's the fault of BSD's to not adopt or change to a better License at getting contributions back to its mainstream.

I also have major objections to calling anything more secure. No software is secure, each one of them has bugs. Some are discovered because more and more people use it. It's not like BSDs never had any CVEs ever.

It is not unfair, because the majority of "developers contributing to it" are on those company payrolls, 8h a day during a full week.

It would be just another BSD or Minix if it would be only university students and weekend coders working on it, and we would all keep using Solaris, Aix, HP-UX, Tru64, Ultrix....

As for security issues, it helps that Linus is against disclosing security bugs as such.

> It is not unfair, because the majority of "developers contributing to it" are on those company payrolls, 8h a day during a full week. Why don't the devs at those company contribute to BSD then? Care to reflect on this?
MIT license, they don't need to.

How much code do you think they got back from Sony, Apple, companies selling routers with BSD on them?

Even Google prefers to build their own OS from scratch with MIT license (Fuchsia) than keep on using Linux for that effort. They already reduced GPL use to the bare minimum on Android by removing gcc.

Then there was the whole suit which made most companies loose interest to be involved with BSD.

FreeBSD uses BSD License, no? Or am I missing something here? https://www.freebsd.org/internal/software-license.html
BSD and MIT licenses are almost interchangeable regarding requirements to the code.

They even appear as MIT/BSD in many projects.

Citations/Examples, please? I always thought these are different.
Simple Google search.

https://opensource.stackexchange.com/questions/217/what-are-...

Relevant part:

"o what both the 2-clause BSD license and the MIT license have in common are:

    Permits use
    Permits redistribution
    Permits redistribution with modification
    Provision to retain the copyright notice and warranty disclaimer
In addition the MIT license also explicitly allows:

    merging
    publishing
    sublicensing
    selling
However, all these freedoms are implied by the BSD license, because all these activities can be considered "use" and/or "redistribution" of the software.

The practical differences between the 2-clause BSD license and the MIT license are marginal. Which one to pick is mostly up to personal taste. Especially considering that both licenses are considered compatible, so you can take code under one license and use it in a project under the other, as long as you keep the license text around."

Yocto has files with such dual license.

https://git.congatec.com/yocto/meta-openembedded/blob/fido/m...

> It is not unfair, because the majority of "developers contributing to it" are on those company payrolls, 8h a day during a full week.

This is overwhelmingly true now, but it wasn't always.

Which is the reason why Linux moved beyond yet another UNIX clone hobby project.

I still remember how it was when I was getting distributions via Walnut Creek CDROMs.

As per Wikipedia, IBM, Compaq and Oracle started contributing in some form around 1998.

I guess we could look at commits history to see when IBM and friends actually started to provide features.

What are you talking about? BSD sees plenty of use, for its support of zfs, dtrace, and jails alone.

Unless you're heavily invested in the Linux kernel and Linux-only tech, I'd advise to keep your software running on the BSDs as well as Linux to avoid monocultures in your own best interest. The strength of F/OSS is in giving you choice, eg. by providing two (or more) interchangeable, excellent O/S's and compiler suites.

I am talking about comparable usage. Do not get me wrong. And it's best for everyone if BSD succeeds because then we have a choice. My pet peeve is that it is incredibly difficult to contribute to BSDs (say OpenBSD) compared to Linux. F/OSS project runs on community contributions and thrives solely on basis of that. I hope they open the process up more so that more and more users contribute to it.

Also, essentials things like graphics drivers etc, work properly so that the devs like us start using it as a daily driver and contribute to it's usage.

Windows NT. Linux not only killed off the existing commercial Unix's it also stopped Microsoft's takeover of the server space.
first thing I do when I see a Linus email: ctrl+f "braindamage".

never disappoints.

I search for "garbage" or "trash"
I think we are at the point where someone just needs to put up a Linus swearing email tracker with analytics and shit and stop posting these threads. We have to come to the realization that the discussion on this is:

a) useless- doesn't change anything b) the publicity is affecting the other side more

So basically Linus is Trump

I really love that he is the way he is. Smart and honest. Nothing like Trump.
(comment deleted)
Not sure what the word "smart" means but he is surely pragmatic and based on such emails looks like he gets easily frustrated.
He gets frustrated with people that are supposed to be experts but that don't match up to that in practice (in his eyes at least)
Nobody is expert and everybody makes mistakes. He should probably lower his expectations.
You don't write Kernel and maintaining quality by keeping low expectations.
(comment deleted)
"Smart and honest" is literally the justification Trump voters would usually employ.
Oh, that's cute. The mere fact that you say that makes it clear you have no idea who Trump is.
A celebrity who speaks with a highly authoritative voice whether they have any idea what they're talking about or not. Sounds about right.
Do you have a link to where Linus talks in a highly authoritative voice when he has yesn't idea what he's talking about? All the cases I've seen where he's talking in an authoritative voice have been about topics he's an expert in.
I mean, just google anytime he talks about security or licensing. And, frankly, people more expert on, say, C, than Torvalds, are dime a dozen. Okay, a large heap of dimes, but still. They just tend to swear less, and in the OP you can see them defering to him to deescalate the situation.
It's not interesting to argue about who's "more expert". If Linus is just "slightly expert", that's very far away from having no idea what he's talking about. My claim wasn't that Linus was the "expertest" C programmer in the world.

I'm neither an expert in security nor in licensing, most of the things I've heard him say about either sounds pretty reasonable. Could you link to an example where he talks out of his ass, and explain why what he's saying is stupid? Both licensing and security strikes me as the kind of thing the author of the world's most used FOSS kernel has thought a lot about.

Linus invented Linux and git. He very much is qualified to talk about his oppinion on aliasig rules. Frankly, anyone who has worked in C is. But, if we're going to play the call to authortiy game: who the fuck are you and what have you done?
(comment deleted)
Come on, this is wonderfully blunt!

> In fact, I'll take real toilet paper over standards any day, because at least that way I won't have splinters and ink up my arse.

You can be blunt without being rude. Most of the post is just rudeness.
Rudeness is a cultural variable.

An Englishman saying "that's interesting" can be more rude than someone else saying "get lost"

Here is a slightly more readable version that's not white-on-white, half-pixel-thick text: https://lkml.org/lkml/2018/6/5/769
Reading on a 400dpi 300nits screen in a slightly dark room, the lkml link hurts the eyes significantly more.

Reading on a shitty 96dpi 100nits screen from 2004 in a bright room, the lkml link is the more readable one.

Another situation of the eternal issue of "we need a web standard for specifying relative contrast", not "make everything blinding #000 on #fff".

Or perhaps do not specify any dumb colours, let the browser do its job of presenting things.

Oh wait, you know you can switch CSS to default layout? Perhaps the browser could use an option to still apply layout but ignore formatting and colours.

The problem is that browsers are generally really terrible at presenting text in a readable and good-looking way. Compare http://motherfuckingwebsite.com/ and http://bettermotherfuckingwebsite.com/ - most people would agree that the second is significantly easier to read.

I really wish browsers' default formatting could be trusted to be as readable as possible, but alas.

Also useful would be a standard way to normalize the apparent size and weight of different fonts so the fallbacks won't look like shit. Apparently my problem is more with the Courier font bundled with Ubuntu, as replacing Courier on that page with just about any other font makes it somewhat readable (still a "disabled" gray, but at least visible).
By the CSS2 standard, #000 and #FFF are sRGB colours, with #000 targeting 0.2cd/m^2, and #FFF targeting 80cd/m^2, with adjustments for ambient light level.

With CSS4, you can choose other colour-spaces instead.

The web standard is there, but so long as 99% of users have setups which emit 300+cd/m^2 and say they're emitting 80, you can't do much with it.

The push toward HDR displays gives us another chance to 'get it right' wrt calibration, but a quick google search of 'HDR washed out' demonstrates why it's an uphill battle to get consumer displays to be honest.

Yeah, it's a major issue — and with CSS there's also no easy way to set HDR colors either.

Hell most displays nowadays don't even do sRGB, which was defined as the colorspace and contrast of an average 1990 CRT.

Linus has done some (okay, lots of) wonderful stuff. However, his attitude here is pretty extreme. Being incredibly rude, then proceeding to merge said pull request. If Linus is willing to merge the PR, then it can't be that bad. Surely there was a more tactful way to approach this, even for Linus.
Why should he NOT being rude? Has anyone ever answered him in the same way? Has anyone ever publicly explained him that while being a sociopathic nerd he still must comply to some basic rules of conduct like we all do. The guy is willingly putting on and supporting the public image he's got and, obviously, loving it. I know, that he's smart and what not, but why should it be an excuse for being an asshole? I just realised that he reminds me of Taleb.
> Has anyone ever publicly explained him that while being a sociopathic nerd he still must comply to some basic rules of conduct like we all do[?]

Yes.

Back in 2014 several DebConf attendees publicly confronted Torvalds, quoting some of the outrageous things he's written to/at people and making him explain himself. It makes for some rather cringy moments and there is no evidence it had any meaningful impact on him. You may watch it all here:

https://www.youtube.com/watch?v=5PmHRSeA2c8

>Why should he NOT being rude? Has anyone ever answered him in the same way?

Several, but no one that mattered enough with respect to Linux for his opinion to matter in return.

His OS, his rules. Others can always fork it if they have an issue with that.

It seems to have worked fine as a gatekeeping technique for the last 25+ years, even if it hurts some feelings. Linus goes for an in-the-trenches, rough camaraderie, approach, rather than a "professional soft spoken cubicle workers" approach.

Linus goes for an in-the-trenches, rough camaraderie, approach

He's an outright toxic and abusive person. Characterizing a lack of toxic, abusive behavior as "professional soft spoken cubicle workers approach" is disingenuous.

Well, if he was "outright toxic", then he would have had negative effects on the kernel development. Which I don't see happening.

So what people mean with that is not that he actually has a toxic effect, but that they dislike his tone.

This is a malformed argument.

Having a 'toxic' personality does not mean he will produce bad code. Two completely different things.

I didn't say that "toxic = he'll produce bad code".

I said that the claim of those saying he's language is toxic is that his language poisons the Linux kernel community development.

And yet, I counter-argue, I see it doing just fine, and going from strength to strength, over the last 25 years. If there's any toxicity effect, I wont see it affecting much, if anything.

I could accept that it might have led some people who could have otherwise contributed away. But I don't see this having any substantial effect on Linux's development.

Perhaps it's even beneficial (since the outcome and results from Linux's development team is better than from any other Unix-like OSS OS, with their supposedly not toxic leaders).

If that freedom of language is all it takes to keep Linus happy, and stewarding the project as well as he has done all these decades, then so be it...

He explicitly says the changes are fine. It's the argument that they should be merged 'because standards' that he's objecting to.
>Linus has done some (okay, lots of) wonderful stuff. However, his attitude here is pretty extreme. Being incredibly rude, then proceeding to merge said pull request.

He already writes that he's OK with the code ("can live with it") -- he's against the reasoning that accompanies it.

Good code or not, if he doesn't agree with the reason to merge it, why merge it?
Presumably, there was a follow-up discussion.
Because the code is OK, but the _rationals_ in the commit message (union aliasing is bad) are not.

This is for history. If someone, later, say: "We should use union aliasing to fix this", someone would argue "No, we shouldn't because we already states _there_ that union aliasing is bad".

You can't consider a such amount of code like the kernel one without its commit history.

Here Linus explain why union aliasing is not "bad" per see, but considered "bad" because the C standard say so and he clearly explain standards are not holy book and compiler implementation is as important (something he always states).

But if he doesn't agree with the commit message, then asking for an altered PR with a different commit message is surely the way to go. Having to trawl the mailing list for maybe-happened-discussions seems like a stupid way to organize things. Maybe I just don't know how they structure the kernel development and documentation.
Make this construct legal behavior without making it 10x slower than clang/gcc are today:

  void wat(uint16_t *x, uint16_t *y) {
    *x = *y;
  }

  uint64_t a[100] = { 0 };
  wat((uint16_t *)&a[0], (uint16_t *)(((char *)&a[0]) + 1));

When you think you've figured that one out, try this one:

  uint16_t heh = 0xFFFF;
  extern uint16_t doesAnything(uint16_t *, uint16_t *);
  void wat(uint16_t *x, uint16_t *y) {
    *x = *y + doesAnything(&heh, y);
  }

  uint64_t a[2] = { 0 };
  wat((uint16_t *)&a[0], (uint16_t *)(((char *)&a[0]) + 1));
Missing the point. Linus was talking about union aliasing.
It's important to bear in mind that Linux isn't written in standard C - it's written in a dialect of C implemented by recent-ish versions of GCC (there is a particular minimum GCC version supported), with certain compiler switches.

There's nothing wrong with this - it's an important enough project to be able to make those kinds of demands.

Android kernels are built with Clang. So really it's just missing support for MSVC, for obvious reasons.
Clang was made to support GCC extensions and be as close to a drop-in replacement for GCC as possible. Linux misses support for MSVC, Intel C Compiler, XL C and basically every other C Compiler ever written except for these 2.
Clang doesn't support every GCC extension, though. For example, nested functions is something that it doesn't do.
Yup. And that one is a deal-breaker for me.

Nested functions is exactly how you would write it in assembly.

Does anyone know why clang won't support them? "Blocks" are fucking stupid.

Because throwing a trampoline on an executable stack is a hack and a glaring exploitation vector.

http://lists.llvm.org/pipermail/cfe-dev/2015-September/04503...

Straw man.

GCC doesn't use a trampoline for the following code:

    long f1 (void) { long i = 0; void f2(void) { i++; } f2(); return i; }
    int main() { return f1(); }
So maybe David Chisnall doesn't know what he's talking about? Or maybe he's talking about a specific use case further up the thread. I'm not going to speculate.

But to edify on my "Blocks" are fucking stupid throwaway, in clang you can do this:

    long f1 (void) { __block long i = 0; void (^f2)(void) = ^{ i++; }; f2(); return i; }
    int main() { return f1(); }
which is close enough I could almost paper over the syntax differences with macros, but clang produces unnecessary allocations(!) which are completely unacceptable for my targets and make clang unworkable for me -- even if I could stomach the dogshit assembly that clang produces during testing and continue to use gcc on the packaging server.

Surely clang could simply disallow passing the address of the nested function, if it's trying to protect people from themselves?

For now, at least [1][2]. See the rest of that thread.. llvm guys really don't want asm goto, and kernel really wants it.

[1] https://lkml.org/lkml/2018/2/14/724 [2] https://lkml.org/lkml/2018/2/14/157

Well, yeah, that's what the other commentators here misunderstand. Sure the kernel is C, but a non-optional part is assembly in various forms that obviously is not standardized between compilers. So it takes effort to support kernel building. Google paid up and made that happen.
MSVC doesn't support all of C99 anyway.
There's no such (real, usable) language as 'standard C'.
Nothing is really written in "standard C".
I never really understood why people complain about Linus personality. If you don't like it go somewhere else nobody is forcing you to code for Linux.

Fork it and make your own.

Right, but why does an adult have to behave like a spoiled little princess anyway?
Funny, that people adore when Linus does it, but dislike when somebody else does that to Linus... Okay, whatever.
It's actually like a rough drill sergeant.

"Spoiled little princesses" are those that can't take some strong words and need hugs and smiles...

It's also people who throw fits with little provocation when they don't like things, which sounds fitting to me. Seriously, the thing gets merged anyway but he has to "express himself"
I found your post aggressive. Will you please change it to appease me?
I see what you're doing, and it doesn't make any sense. I just said I didn't like a pointless display of emotion, and so you do a "satirical" emotional appeal?
> Fork it and make your own

Even Google couldn't pull that off with Android.

Another question is would Linux become what it's become if everyone would really have just forked it?
Another question is would Linux become what it's become if only nice polite guys were allowed to code it?
That's irrelevant, nobody's talking about allowing or not allowing to participate, but accepting help while insulting the helpers, seems disgusting to me and I really find it weird that some people readily accept that while demanding respect and politeness in other situations. Double standards – that's what it is.
I don't see him here "insulting the helpers". He's saying the argument for this change is bad, he's saying a bunch of things in the C standard are bad, but there's nothing personal there.
Then you do not understand the whole point of asking this question. Its speculative whether the counterfactual "Linus is nice to everyone"-Kernel would be better or worse. Both options are possible. Like everywhere in capitalism, just being nice and doing the right thing must not always select you as a winner...
> ... if everyone would really have just forked it?

well, if you can keep pace with it, why not ?

Linus shows this behavior more rarely rather than often (about once a month) and usually in the direction of people he knows can take a bit of a rant.
Yeh, I get the impression he does it with people he would have a beer with.
Can someone ELI5 what the issue is with type punning and union aliasing?
Suppose you want to look at the bits of a floating point number, as though it were an integer. The type punning way to do that would be to access a double in memory through an integer pointer:

    double d = 3.14;
    int64_t *p = (int64_t *) &d; // !!!
    int64_t n = *p;
The union aliasing way would be to makeset the double field in a union and read the integer field back:

    typedef union {
        double d;
        int64_t n;
    } int_or_double;

    int_or_double u;
    u.d = 3.14
    int64_t n = u.n
According to the standard, the union aliasing approach is allowed, but the type punning one is undefined behavior.

---------

The standard team decided to forbid type punning to allow compilers to implement more optimizations. They still allow union aliasing because they felt there should still be a way to do low-level type casts if for those that absolutely want to.

No, type punning via unions is a gcc extension.

The standard only allows reading a value as the type it was written with or as char, and an access as char is only good for copying. If a char access used different bit order, that would be OK according to the standard because you couldn't tell unless you violated the standard.

It seems every compiler will tolerate a memcpy for type punning, even though this isn't required.

Does this mean that memcpy() is really more of a language construct than a library function, since it cannot be implemented correctly in fully defined standard C?
Everything defined in the standard is in principle a language construct: whether it is builtin in the compiler or an actual function is an implementation detail. For many compilers, memcpy is both: they have builtin handling for it but fall back to the library implementation when there is no optimization opportunities.

Having said that, it is possible to implement memcopy in standard C: char pointers have an explicit special exemption to the aliasing rule so you are allowed to inspect objects as array of chars.

memcpy is legal and fine. To borrow the example from above:

  double d = 3.14;
  uint64_t i;
  memcpy(&i, &d, sizeof(d));
is perfectly kosher.
> is perfectly kosher

Aren't exact-bitwidth integer types optional even with C99 (let alone preceding versions of standard)?

They are optional, but only in the sense that if you can't exactly represent e.g. uint64_t, there can't be a uint64_t type. So the example above is kosher in the sense that it's standards compliant, even if it isn't perfectly portable (for reasons unrelated to memset type punning; that you're using uint64_t in the first place).

If an implementation can't represent uint64_t exactly, it can still have a uint_least64_t type of whatever width works.

(comment deleted)
I certainly agree with what you said as you said it. However, as usual, it is the implementation that kills it.

a) I believe sizeof (double) * 8 == 64 is not enforced by the standard either. One could argue that it is hard to find anything else these days, but (for a contrived example) I believe nothing prevents you from making your own port of GCC for some purpose, and make 'double' be 'float'. (From my memories, it is even far enough from rocket science.)

b) It already happened to me personally, to work with code where people have implemented their own uintXX types (because of the lack of the standard ones), and then over time these became narrower/vider.

So if we would like to have it portable, I think, nothing beats:

union { double d; char cc [sizeof (double)]; };

and there we are, back to what is in the standard.

I mostly agree, but with b) IMO the problem was that you worked in an environment that was already not concerned with the standard. I'm not sure if it's OK by the standard for a user to define types named e.g. int32_t that don't comply to the standard restrictions.

sizeof (double) can be guaranteed to be 8 if __STDC_IEC_559__ is defined, so checking that is an additional hurdle if you want to use memcpy for punning. That said, I think it can be assumed that you're writing non-portable code for a specific set of platforms already if you are punning floats to integers, because the representation is implementation dependent in the first place. Probably you also know the environments in which it will be compiled as well, so the example is a bit contrived.

Very much agree that unions are the easiest and standard way to do type punning. There's so many misconceptions about this somehow being unclear in the standard. Sure, it does reflect poorly on the quality of the standard that Linux contributors don't understand it and that Linus Torvalds actively ignores it, but if you know what you're looking for it's often not that hard to find a definite answer.

AFAIK even using union for the above purpose can be seen as "undefined behavior" when reading standard, and that's why the standard is especially wrong, as it makes some typical desired (and needed) outcomes impossible to implement, and at the moment clang still has problems even with the union variant whereas gcc allows you to use union by passing the compiler switch which effectively has the semantics "we promise we won't listen to the standard in this case."

That's why Linus writes:

"So the commit message that talks about how horrible union aliasing is is pushing a story that is simply wrong."

The commit message with which he disagreed obviously explicitly wrote something like (paraphrasing) "using union is undefined behavior by standard, so we are changing the code to not use it" etc.

Linus also wrote: "I'm not talking about the changes themselves - I can live with them. But the _rationale_ is pure and utter garbage, and dangerously so."

The rationale was (note, I don't have exact quote, I'm paraphrasing, if somebody has the original please give a link) that using unions for that is bad as per standard. Which is what the standard says but which is for practical purposes simply wrong. The standard is wrong an should not be followed, that was main Linus' argument.

What part of the standard should I read to come to the conclusion that type punning with unions is undefined behavior? C99 and C11 both explicitly mention that it's not, but maybe you're talking C89/C90?

IMO there are 4 highly relevant paragraphs in C99:

6.2.6.1: When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values.

6.2.6.1: When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values

6.5.2.3 DR283) If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning").

6.7.2.1: A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.

None of this implies that unions can't be used for type punning. What it does imply is that reading from a larger member of the union than you last wrote to will leave you with an unspecified value.

I think the clang and gcc contributors consider all this in combination with “strict aliasing” and “type” consistency attitude effectively if you just wrote a double to a union member, you can’t expect that reading integer from the same union has any meaning at all so they optimized that away “per standard”. To come to that, it’s not what is explicitly written when you do a keyword search for “union” but what is not said that it “must work” in spite of other “must work” and “undefined” standard statements. But ask them for the details, I’m just following the topic and have no active involvement.
> if you just wrote a double to a union member, you can’t expect that reading integer from the same union has any meaning at all so they optimized that away “per standard”.

gcc 4.9.2 for sure does not (-O3 -fstrict-aliasing). Not sure what clang does, but I'd be surprised if it ignores the standard. The standard makes it pretty clear what meaning it will have. Sure, gcc and clang maintainers may seem to read the standards like a lawyer looking to void a contract, but in this case it is actually very clear what they should do.

> what is not said that it “must work” in spite of other “must work” and “undefined” standard statements.

The standard makes it clear how to deal with the semantics: "In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object)." Only constraints directly use "shall"/"shall not" type language, but the expressions should still be evaluated as specified by the semantics.

Googling I've found for example this:

GNU extensions to standard C++ (and to C90) do explicitly allow type-punning with unions. Other compilers that don't support GNU extensions may also support union type-punning, but it's not part of the base language standard.

Also, apparently in C99 one relevant statement was:

“The value of a union member other than the last one stored into [is unspecified]

https://stackoverflow.com/questions/25664848/unions-and-type...

Note: In case it's not obvious, I, personally, believe that, at least, using unions for type-punning has to exist and should be explicitly supported in the standards too. And that the compiler contributors should not produce practically unusable results even when some standard is wrong (for common use) or unclear. But the quotes like the above give a hint on which basis some try to cling to bad approaches in this special case. In other cases it's probably even harder to avoid unwanted results.

Several compiler optimizations center around proving which variables don't change. Allowing type punning makes it harder for the compiler to do this.
To me, this rant seems more directed at C standards people than the guy he sent it to. That doesn't excuse his vitriol, but I hope people will read between the lines.

Sometimes people forget that C was created for writing operating systems. They get in their mind that C is all about high-performance, and that making it competitive with FORTRAN is the way to go. I understand that, but it's not what C was created for. If the world's most famous C programmer and OS guru wants to have strong opinions on the direction of the language, I say allow it.

Yes. From the article: " The standard simply is not important, when it is in direct conflict with reality and reliable code generation."
His rant seems directed against the _argument_ that standards should be followed without question.
>C was created for writing operating systems

That doesn't properly justify C's minefield around aliasing and type punning in general. It's UB galore. Thing is, whenever you're writing low level code that's tied to hardware in my experience you very often end up having to pun your types to match hardware constraints, and at this point the C standard basically says "lol good luck with that bro".

I'm not a programming language expert but IMO at the very least C should make reading from a different union member than was last written to "implementation defined" instead of UB (with suitable constraints if the sizes of the members differ I suppose). In effect that's mostly how compilers deal with that anyway.

So I agree with Linus that the C standard is really unhelpful in these situation, although his childish anger is unnecessary and counter-productive.

>at the very least C should make reading from a different union member than was last written to "implementation defined"

That's how it is :) The standard even describes union behavior as "type punning".

I don't know if C++ allows it though.

Don’t think c++ allows it. Last time I checked, if you use any modern compiler, and do a memcpy, and check the assembly, it does the right thing.
Yes, that's the "approved" way of doing type punning. Any decent compiler will immediately optimize that down to nothing.
You're right, apparently it changed in C99 so my knowledge is pretty out of date. Thank you for pointing it out.
Type punning through a union is allowed, buy you have to be careful so the compiler can see the union.

union { int i; float f; } u;

You can't safely call a function with pointers to the members like func(&u.i, &u.f), because when func was compiled, the compiler couldn't know that the arguments are pointers to union members.

This sort of thing scares me, because what the compiler can "see" isn't well defined. Is it ok if func is in the same file? Probably not. How about if I don't send the pointers to an other function and just use them locally? Probably ok, but I wouldn't trust it. If you want to type pun with a union, make sure to always access the members through the union, not with direct pointers.

The only method of type punning I 100% trust is memcpy, and if you get lucky the compiler might optimize away the overhead for you.

Assuming we're talking C, not C++, the compiler doesn't need to know that the arguments are pointers to union members, because the union members are all aligned with the union itself and have the same address. So &u.f is not some magic special pointer, it's the address of a float. So is (float *)&u. The example in the standard I think you're referring to relates to a special guarantee made about unions of structs that have a common initial sequence, that their common initial sequence can be read from either union member (AFAIK a guarantee not otherwise made about structs that share a common initial sequence).

If your func(&u.i &u.f) example fails it may be because the standard is picky about pointers of different types to the same memory. I have no idea whether it is, because I've never had to do anything like your example.

The func can be implemented like this:

    float func(int *i, float *f) {
      *i = 42;
      return *f;
    }
Since the compiler assumes that the pointers i and f do not alias, it has a right to generate the code that is equivalent to:

    float func(int *i, float *f) {
      float result = *f;
      *i = 42;
      return result;
    }
But this will change the result of the function. So in practice if you want to do type punning using unions, the compiler must know about it.
Sure, by not accessing the members through the union type you lose the information the compiler needs to relax strict aliasing assumptions for union access. It's a potential footgun, but IMO only with careful aiming. It's also not strictly related to union member pointers but applies generally to aliased pointers.
The compiler and standard are both full of contradictory, useless, and counter-productive rules on aliasing. But both gcc and clang now support _may_alias_ and -fno-strict-aliasing without which they would have made the language completely unusable.
Maybe I suck at reading the standard, but it seems that type punning via unions is defined in C99:

"If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning")."

The problem is in how the gcc (and to some extent clang) maintainers read the standard.

If the C standard says: the following construct is undefined, then as a compiler writer you have two options: you try to figure out what is sensible in this context, or you do something crazy that conforms to a literal interpretation.

For operating system code, you want the compiler to something sensible. Life is already hard enough. In just about all cases where the C standard introduces undefined behaviour, there is an obvious interpretation that makes sense to most C programmers.

If you want to get the highest possible score in a benchmark, you write a compiler that drops code left and right if you can prove that the code invoked undefined behaviour.

Unfortunately, compiler writers, in particular the maintainers of gcc, seem to care more about this ratrace than to write a good compiler for compiling operating system code.

> If the C standard says: the following construct is undefined, then as a compiler writer you have two options: you try to figure out what is sensible in this context, or you do something crazy that conforms to a literal interpretation.

Not exactly. Rather, the compiler is not constrained by any particular behavior of the construct which is said to be undefined. So if there is an optimization that changes the meaning of the undefined construct, it's all fair game, because the construct was not defined in the first place.

That's exactly the problem. Somewhere a programmer working on a compiler is coding an optimization that make a program run faster, but gives a different result from what the writer of the program intended.

That's only useful if you only care about the total run time of the program and not about what it is trying to achieve.

Except "strong opinions" is not what happened here. He's being verbally abusive.

I think it'd be helpful to be able to talk about this behaviour without needing to suger-coat it as "opinions".

There are far less damaging ways to say exactly the same things as Tovalds says, and someone with his position in the community should know better.

Punch up if you like, not down.

I think he's not really ranting at the guy submitting the patch. He's ranting at the the c standard committee and the compiler maintainers with their optimization fetish[1]. While at the same time redrawing a line in the sand.

[1] It's an open secret that most of the optimizations introduced in the last ten years provide no real benefit while making programs harder to reason about and trust. While at the same time the gcc backend is a trashfire. Hint, Microsoft's VC compiler produces better assembly code without any of these 'optimizations'

I'm in no way offended by Torvalds' typical expletive-laden rants. But they do strike me as a terrible way to communicate.

These outbursts seem to happen every few weeks, and have long seized to surprise. IF anything actually bad ever comes up, he has no further escalation available to raise awareness.

It also reminds me of these choleric bosses screaming at someone every day: it's almost always a sign that they're insecure, sociopaths, or can't handle their responsibilities.

This is the actual reason his manner of communication is poor - swearing and generally blunt language like this should be reserved for shaking people into action, whether it's due to their otherwise ambivalent attitude or the severity of the situation. By making a big fuss for every moderate concern he has, he leaves few options open for when the situation demands that people spring into action.
Linus Torvals says something technical and full of insights while keeping control over emotions - crickets nobody cares.

Linus Torvals adds some insults into the above or simple does not even attempts to keep control over his emotional side - half people jump up and down happy like a fourteen years old. Wow, look, he used insult! The other half suddenly turns into prude "I never swear nor insult anyone" Victorian aristocrats - despite having tweet feeds full of, and I am quoting here, "fucks".

I work with a codebase that implements a sort of OO inheritance in C. It looks like this:

    #define BASE_FIELDS int a; int b; int c;

    struct Base {
        BASE_FIELDS
    };

    struct Derived1 {
        BASE_FIELDS
        int d; int e;
    };

    struct Derived2 {
        BASE_FIELDS
        int f; int g;
    };
Then, it has lots of code that accesses Derived objects through a `Base*`, with ->a and so on.

Is this against the standard C aliasing rules? If so, how would this need to be rewritten to conform to the standard?

It is against the rules. To fix that, you'd need to put a field of type 'struct Base' in the derived struct(s) rather than just copying its fields.

edit: If you want to keep the existing syntax and can use GCC extensions, it should be legal to use an unnamed union:

    struct Derived1 {
        union {
            struct Base base;
            struct {
                int a; int b; int c;
            };
        };
        int d; int e;
    };
edit2: or, with -fms-extensions, just

    struct Derived1 {
        struct Base;
        int d; int e;
    };
Putting a field of type 'struct Base' adds extra padding in my case, unfortunately.
I believe there is a way to disable field alignment on a case-by-case basis. I could be wrong, though.
Yes, there's the GCC extension __attribute__((packed)), or #pragma pack, an extension supported by both GCC-style compilers and MSVC.
originally fields (or rather structure offsets) in C were GLOBAL and could be used with any struct pointer, the Unix V6/V7 kernels used this to good effect, because of this unions weren't really needed (you just used a different field name from a different structure)
That is well-defined.

"One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the complete type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members."

This does technically require that a union of those structs exists, even though it is not used. I don't know of any compiler for which this actually makes a difference though.
Ah, I misunderstood the context, you are right to clarify this.
I checked and we actually have a give union for everything. I didn't mention it because I accidentally got rid of it when simplifying my question (the original is full of macros).

Looks like we are in the clear! :)

Notice that after his rant, he still tested the code, and merged it: https://lkml.org/lkml/2018/6/5/774
Well he did start the rant with "I have no problem with the code, it's just the rationale that I disagree with." And from what I've seen, Linus is nothing if not pragmatic. Good code is good code regardless of the rationale.
Which shows how pointless the rant was.
I have no problem with the rant, just question its emotional source (presumably negative emotion from other areas of his personal life)
If you have invested 20+ years of your life into a particular project, and you have someone doing something that you consider potentially harmful to it, could that not be enough to react angrily?

I don't see why it would need to be negative emotion sourced from another area of his life that is leaking out here.

You presumably have to be pretty emotionally invested in something to work on it that long as a hobby and only later as a job.

When people can't find fault in the technical argument, they start attacking other things like. > Oh! He is so rude, He insults so much.

If you have a better argument to counter his logic, please post that, it would be more useful for everyone involved. Posting pretty useless comments here is pretty lame.

I'll critique his prose on efficiency grounds. He wastes many words making a point.
Let's stop policing speech, alright? You can use as many words as you want to express your views. I personally would not use the same words he might use, but let's not be hypocrites and say that none of us have written an angry or frustrated response to something that we think is stupid and just plain wrong.
I posit that there is no policing here. By what definition is there policing?

Speech is a topic of discussion just like anything else under the sun.

(And also: People here have no authority or power to police anything.)

I did use as many words as I wanted.

You can take as many steps as you want to get to the mailbox too. And you'll be taking more steps if you detour to go sniff dog shit. Going in a straight line solves two problems - it's faster and it smells better.

Wait, so according to you it's OK to be as rude as you wish, as long as you are technically correct?

I think most people couldn't care less who's right or wrong in this discussion. They are simply reacting to the discourse.

Personally, I'm far from convinced that there even is an objective right or wrong in this question. It's probably just a matter of taste and/or perspective.

I find Linus behavior rude because in discussions like this he seems to have little to no understanding of other perspectives than his own.

Either that or he is deliberately provoking this other fellow to get him off his high horses.

In either case, it's not exactly accepted public discourse.

He has said himself that he needs to do this to drive his point across, and given the medium and audience I can agree that the political challenge of running the project must be huge.

But surely there must be a more diplomatic way to the same end?

> Wait, so according to you it's OK to be as rude as you wish, as long as you are technically correct? I never said that. My argument is that people/culture are different. What is considered offensive/rude in some culture is considered normal in other cultures.

> Personally, I'm far from convinced that there even is an objective right or wrong in this question. It's probably just a matter of taste and/or perspective.

This is not always true. Sometimes there is only one correct/pragmatic way of doing something. And if someone asserts that it's nothing wrong.

> I find Linus behavior rude because in discussions like this he seems to have little to no understanding of other perspectives than his own.

You can't say this is the case always. I have read a lot of the discussions like these. A lot of times, he writes a pragmatic and valid explanation of his dislike about a certain topic.

> In either case, it's not exactly accepted public discourse.

Again, you are assuming all cultures and societies are alike, they are not. There is a vast wide world with different thinking and a culture other than the Silicon Valley bubble. It's time people stop generalizing everything under the sun.

"So what's the _real_ reason for avoiding union aliasing?"

Gee, Linus, you couldn't just Google "Reasons to avoid union aliasing" and see posts going all the way back to 2011 griping about how it screws even the most basic code beyond repair?

Doesn't C have something better than that type punning via union to achieve the same effect? I understand Linus reasoning, but still it's an ugly hack.
Type punning to char* is explicitly allowed. (But going from char* to any other type is not...)
Also you're only allowed to read that char
See other comments, some variant of "type punning via union is not allowed according to the C standard" is what made Linus responding like that. Moreover, even using union for that is a compiler switch in gcc, to avoid compiler following "the standard." Linus points that following the standard is definitely wrong thing to do:

"When documented gcc behavior says one thing, and the standard might be unclear, we really don't care one whit about the lack of clarity in some standard."

I think the union thing was at least initially implemented as not functioning at all in clang, where developers "followed the standard."

i really wish a person many software engineers idolize or at least obviously respect and pay attention to, myself being excluded from these camps, didn’t communicate like a child.

it’s an embarrassment for the field.

raises hand I would love to be able to contribute to the linux kernel one day. But I'm unlikely to ever become part of the community when its leader behaves like this.
You have to realize that extreme PC thing is very US centric and pretty recent at that.
PC? This is not politically correct, this is an opinion based on free will and self-respect. “I don’t want to volunteer where the boss is an abusive asshole.” By what definition is that PC?
using profanity and being "abusive asshole" are orthogonal concepts. I obviously do not encourage anyone to volunteer in projects they feel uncomfortable with.
They may be orthogonal. Often, however, they are related.
using profanity and being "abusive asshole" are orthogonal concepts

In this sub-thread, you're the first one to bring up swearing.

I'm not American. I'm just a respectful human being who expects to be treated with respect at work.
Use of profanity is pretty orthogonal to respect but again it's very culture specific thing.
And in my opinion there was nothing disrespectful in Linus'email (expect towards the standard people, but they truly did a big mistake..) so I wouldn't want to work with you as you seem 'overly sensitive'..
Big mistakes happen.

Solutions to those mistakes are rarely found by publicly demonising those who made the mistake.

> publicly demonising those who made the mistake

But that isn't what is happening here at all. This code was merged. In fact Linus wasn't even yelling at the guy, rather the standards committee.

Just because you don't read 'atta boy, good job' doesn't mean it wasn't good. There was no mistake here.

In fact I'd be on your side if that is what he was doing.

I don't think you have to worry here. Even as a kernel contributor, you'd likely never interact directly with Linus.
> The fact is that gcc documents type punning through unions as the "right way". You may disagree with that, but putting some theoretical standards language over the explicit and long-time documentation of the main compiler we use is pure and utter bullshit.

this was the whole point of the rant.