Live data from Hacker News

Initialization in C++ is Seriously Bonkers

mikelui.io

91–100 of 130 posts

Re: Initialization in C++ is Seriously Bonkers

#91
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…

On the contrary, properly teaching pointers can do wonders to help people understand how memory is structured.

C and C++ are horrible academic languages for other reasons - the original design is just too much of a hack to begin with, and then there's decades of legacy backwards compatibility with it in all newer developments. Syntax is ugly and inconsistent, doing things right is often harder than doing them wrong, there are many features and exceptions that are only there for historical reasons, and standard library is very eclectic in terms of what is and isn't included (from a modern perspective). But take something like Modula-2, and pointers aren't a problem.

Re: Initialization in C++ is Seriously Bonkers

#92

Earlier quoted context omitted.

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 eff…

A better idea is to force the initializer, and require some special syntax if you really want an uninitialized variable. E.g. if a language uses underscore as a syntactic wildcard, then it could be something like:

   int x = _;
The vast majority of variables can and should be initialized when they're declared (and often don't ever change after, so const is a good idea too). This is especially so in C++, which is less likely to return values via references/pointers these days (with tuples and uniform init for returning structs).

Re: Initialization in C++ is Seriously Bonkers

#93
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…

Why would the code for "const int i" be any different from the code for "int i"? The Standard doesn't require the variable to be allocated in an immutable memory area. It just says that if you do anything to change its value, the result is undefined behavior. And actually changing the value in a way that would be observable via the const variable is a valid subset of undefined behavior.

Re: Initialization in C++ is Seriously Bonkers

#94
post #5

In my view this author falls into the camp of people calling C++ a mess because it gives them too much control when they ask for it. One of his examples which he calls "The Abyss": #include struct A { A(std::initializer_list l) : i(2) {} A(int i = 1) : i(i) {} int i; }; int main() { A a1; A a2{}; A a3(3); A a4 = {5}; A a5{4, 3, 2}; std::cout which outputs: 1 1 3 2 2 he claims to be mysterious but is actually pretty r…

The problem with C++ that the article explores isn't that it's complex. It's that it's unnecessarily complex, and you could have a language with all that power (and then some, like say a proper macro facility) without so many warts. Indeed, Rust is a proof by example now.

Of course, those warts were necessary for C++ to be successful back when it was introduced and competing against others, and therefore to its popularity today. And this popularity is just as much a part of C++ appeal as its power. But we can call them out for what they are, without trying to justify them.

Re: Initialization in C++ is Seriously Bonkers

#95
post #54

How many languages give you that much precise control over memory? So few.

Many sibling languages in the era all of them originally appeared did so - Pascal (not the core language, but real-world implementations with their extensions, like Borland's), Modula-2 etc.

Re: Initialization in C++ is Seriously Bonkers

#96
post #48

> 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…

Hi. I appreciate your candor, although I'm not sure what I've done to inspire such contempt. You're correct that the entire point of the post was to deep dive into a rabbit hole. I acknowledged that and also acknowledged that the standardese is unnecessary most of the time, to avoid any miscommunication in my intent. I did this point out how large the language is and, more to the point, to point out how potentially c…

I am not sure about the following issue: What would make your students more productive?

   - use C++, given that you stick to some convenient subset of C++ and can use stl
   - stick with C and force them to do the basics, like linked lists and string abstractions over and over again.
I guess in the olden days really good students used to develop their own library of C abstractions, and reuse them with several courses; but you can't quite do that if you have C in just one course and what's the point anyway in this day and age ?

Re: Initialization in C++ is Seriously Bonkers

#97

Earlier quoted context omitted.

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.

The OS does initialize it, so if you’re writing code for linux in any languages, or even in assembly, you won’t be able to spy on that retrieved memory. Now C might want to do it too, but bare metal stuff is not necessarily compliant C so that doesn’t matter much.

(Having been the lead for an RTOS) it matters less what the spec says, and more what the compiler expects. So like, you can ignore kill(3) by just not calling it. Patching the compiler to not depend on zero initialized .bss is way harder, and it's just easier to clear it yourself pre main.

Re: Initialization in C++ is Seriously Bonkers

#98
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 reason that stack variables are UNinitialized is (contra the article which thinks it's because the programmer didn't put an initializer in the source code) that memory is on the stack, which is allocated internal to your program and in practice was used previously by some other call for some other purpose. It is because the programmer didn't put an initializer into the source code. That's how the language is de…

"Any C programmer worth anything knows that this initializes i to an indeterminate value. This is wrong. Reading the variable does not simply give you an indeterminate value, it gives undefined behaviour"

Undefined behavior in the technical sense is not acceptable in a language at all, let alone a feature. If you take the idea of undefined behavior seriously, then it is valid to blow up the world in response to an error and the compiler cannot protect you. Nobody would use C or C++ if they actually accepted the meaning of undefined behavior, so to program in these languages requires embracing doublethink.

Re: Initialization in C++ is Seriously Bonkers

#99
post #82

Earlier quoted context omitted.

./libgcc/config/nds32/crtzero.S .L_bss_init: ! clear BSS, this process can be 4 time faster if data is 4 byte aligned ! if so, use swi.p instead of sbi.p ! the related stuff are defined in linker script la $r0, _edata ! get the starting addr of bss la $r2, _end ! get ending addr of bss beq $r0, $r2, .L_call_main ! if no bss just do nothing movi $r1, 0 ! should be cleared to 0 .L_clear_bss: sbi.p $r1, [$r0], 1 ! Set 0…

How does finding some uncompiled sample code someone added to gcc for an architecture no one has heard of refute the point that glibc on Linux implements bss with an anonymous mmap?

Rather than pointing to Linux over and over, let's look at Win95. It kind of comes from a 'fuck local security' standpoint (everything mmaped is in one global space mapped into all processes), and still clears bss because that's what the spec expects, and like a lot of embedded systems is fully spec compliant.

Re: Initialization in C++ is Seriously Bonkers

#100
post #48

Earlier quoted context omitted.

Hi. I appreciate your candor, although I'm not sure what I've done to inspire such contempt. You're correct that the entire point of the post was to deep dive into a rabbit hole. I acknowledged that and also acknowledged that the standardese is unnecessary most of the time, to avoid any miscommunication in my intent. I did this point out how large the language is and, more to the point, to point out how potentially c…

I am not sure about the following issue: What would make your students more productive? - use C++, given that you stick to some convenient subset of C++ and can use stl - stick with C and force them to do the basics, like linked lists and string abstractions over and over again. I guess in the olden days really good students used to develop their own library of C abstractions, and reuse them with several courses; but…

How else would they learn about linked lists and dynamic arrays?
Post reply on HN