Live data from Hacker News

Initialization in C++ is Seriously Bonkers

mikelui.io

31–40 of 130 posts

Re: Initialization in C++ is Seriously Bonkers

#31
post #2

> [Why is a global variable zero?] Because i has static storage duration, it’s initialized to unsigned zero. Why, you ask? Because the standard says so. No, it's because i lives in an area allocated at the OS level, and OS has to have initialized that memory with something (otherwise you'd have a security bug). The .bss segment has been zeroed, for obvious reasons, since the advent of modern linkage. The explanation…

I don't think we should pretend that any of this was planned out. The reason the C standard is like it is because it doesn't just specify the best possible version of C that can exist, but because it encodes historical behaviour. It's possible to post-rationalize those decisions, but as I understand it, there's no particular reason why .bss has to be initialized -- it just happens to be the way Unix has worked since…

> With modern static analysis, there's probably no performance benefit to not initializing stack variables that are read before they're written?

Not really relevant because that's a bug.

But the common thinking "let's always default-initialize stack variables because the compiler will make it efficient anyway" is clearly "sufficiently smart compiler" thinking. Implicit default initialization will never be 100% as efficient as simply not requiring initialization.

Plus, I like the error messages I can get, sometimes, with no default initialization. The compiler can statically detect some uninitialized reads. It cannot do that if all variables are implicitly initialized. In many other cases at least one can be quite certain to experience random crashes that let one track down the bad read rather quickly.

In other words, implicitly initializing to zero normally just hides logic bugs. It doesn't make them go away.

Re: Initialization in C++ is Seriously Bonkers

#33
post #8
post #2

> [Why is a global variable zero?] Because i has static storage duration, it’s initialized to unsigned zero. Why, you ask? Because the standard says so. No, it's because i lives in an area allocated at the OS level, and OS has to have initialized that memory with something (otherwise you'd have a security bug). The .bss segment has been zeroed, for obvious reasons, since the advent of modern linkage. The explanation…

> No, it's because i lives in an area allocated at the OS level What OS? I don't have one. I have to link in init code to zero sections of ram before my embedded code runs. Sure, it got into the standard because some popular OSes like Unix zero initialized pages, but it's not a universal truth. The reason it's guaranteed in C is because of the spec.

Not necessarily true.

C89 only requires that static values be initialized.

A modern C standard (section: 6.7.8(10)) requires static values be initialized, but what the value is initialized too be _technically_ indeterminate.

There is the guide line given that integers must be zero, and pointers be NULL. But if a static storage class isn't consisting of purely integers, pointers, or (fixed sized) structures, arrays, and unions who's elements can recursively reduced to integers or pointers. Then the standard says the initialized value is indeterminate.

While relatively straightforward, there is a few gotcha's.

Re: Initialization in C++ is Seriously Bonkers

#34
post #3
post #2

> [Why is a global variable zero?] Because i has static storage duration, it’s initialized to unsigned zero. Why, you ask? Because the standard says so. No, it's because i lives in an area allocated at the OS level, and OS has to have initialized that memory with something (otherwise you'd have a security bug). The .bss segment has been zeroed, for obvious reasons, since the advent of modern linkage. The explanation…

I always think C/C++ is not a good first language to teach, because you need to understand some general concepts about computer systems before diving in. Probably more than half of the beginners in their first C class give up when handling pointers/arrays - it's not because the concept is hard, but because they have no idea what the "memory" in the computer actually is and how it works. You're left with a naive analo…

Yeah even in the old days Pascal was the language of choice for beginners. Now pythin holds that position although some schools teach java or c# as a first language many use python these days.

Re: Initialization in C++ is Seriously Bonkers

#35
post #17

Earlier quoted context omitted.

In embedded assemblers I have used (TMS34010), the BSS section is uninitialized when the program is loaded (I helped write the OS). When I wrote embedded C, the added C runtime code that executes (before main() is called) zeroes out the BSS section (the OS has nothing to do with it). In other words, it is the C runtime that is responsible for initializing, not the OS.

I think you're the fourth person jumping in to quibble with my "bss is zeroed by the OS" statement by snarking about "Ah hah! But what if you YOU ARE the OS?!". Yeah, I know. I live in that world too. I don't know that it's particularly relevant. The C standard is written to a norm of a Unix userspace environment, and that's clearly where the linked article is working.

It’s the C runtime that zeros it, not the OS. That’s my main point. The OS may initialize too, but that is outside the standard.

Re: Initialization in C++ is Seriously Bonkers

#36

> C++ is not a language I’d want to teach beginners. At no point in this post was there room for systems programming concepts, discourse on programming paradigms, computational-oriented problem solving methodologies, or fundamental algorithms. This is a ridiculous argument. The entire point of the post was, as the author even noted, purely to deep dive into a rabbit hole, get super picky & pedantic about standards wo…

use the new stuff which fixes all the complexity It doesn't, unfortunately it just adds to the complexity.

How so? My experience has been that it actually reduces net complexity, except in the case where you need to support different versions of the language in the same codebase.

Take for example, `auto`, added in C++11. If you don't have to support C++98 or C++03, the use of `auto` significantly simplifies many workflows and is often strictly better with less mental overhead.

Re: Initialization in C++ is Seriously Bonkers

#37

> C++ is not a language I’d want to teach beginners. At no point in this post was there room for systems programming concepts, discourse on programming paradigms, computational-oriented problem solving methodologies, or fundamental algorithms. This is a ridiculous argument. The entire point of the post was, as the author even noted, purely to deep dive into a rabbit hole, get super picky & pedantic about standards wo…

> This is a ridiculous argument.

Please keep it civil. I'm sure you could refute the GP without expressing contempt.

Re: Initialization in C++ is Seriously Bonkers

#38
post #17

Earlier quoted context omitted.

I think you're the fourth person jumping in to quibble with my "bss is zeroed by the OS" statement by snarking about "Ah hah! But what if you YOU ARE the OS?!". Yeah, I know. I live in that world too. I don't know that it's particularly relevant. The C standard is written to a norm of a Unix userspace environment, and that's clearly where the linked article is working.

It’s the C runtime that zeros it, not the OS. That’s my main point. The OS may initialize too, but that is outside the standard.

On oddball platforms it might be (though I think there's some quibbling as to whether the C runtime in such an environment is really distinct form "the OS"). It's not on Linux. The .bss segment becomes an anonymous mmap which is zeroed by the kernel when first accessed. Glibc never touches it.

(Edit to correct: obviously glibc "touches" .bss because it has its own static variables. But there's no "zero .bss" step in crt0.o)

Re: Initialization in C++ is Seriously Bonkers

#39
post #4
post #2

> [Why is a global variable zero?] Because i has static storage duration, it’s initialized to unsigned zero. Why, you ask? Because the standard says so. No, it's because i lives in an area allocated at the OS level, and OS has to have initialized that memory with something (otherwise you'd have a security bug). The .bss segment has been zeroed, for obvious reasons, since the advent of modern linkage. The explanation…

> The .bss segment has been zeroed, for obvious reasons, since the advent of modern linkage. For your amusement: in the Linux kernel , at least on x86, .bss isn’t initialized when the kernel is loaded. Instead, the kernel memsets it to zero a little later. I don’t know why. Also, because all this stuff predates any concept of security, there is no read-only equivalent of .bss in most systems, meaning that you get sub…

The optimal code for const int i = 0; is for the compiler to inline its uses, and for there never to be any storage allocated at all.

;-)

Re: Initialization in C++ is Seriously Bonkers

#40
post #3
post #2

> [Why is a global variable zero?] Because i has static storage duration, it’s initialized to unsigned zero. Why, you ask? Because the standard says so. No, it's because i lives in an area allocated at the OS level, and OS has to have initialized that memory with something (otherwise you'd have a security bug). The .bss segment has been zeroed, for obvious reasons, since the advent of modern linkage. The explanation…

I always think C/C++ is not a good first language to teach, because you need to understand some general concepts about computer systems before diving in. Probably more than half of the beginners in their first C class give up when handling pointers/arrays - it's not because the concept is hard, but because they have no idea what the "memory" in the computer actually is and how it works. You're left with a naive analo…

I learnt C as a first language, and those computer sytems concept were explained as we go. It's not that hard to understand what memory is and that variables values are stored there, and I've had no problem with pointers.

And the big advantage is that when you understand those concept and pointers, there's no magic in other languages (value/reference parameters, objects, functions as first-class citizens)

Post reply on HN