We switched to Rust. Generally, are there specific domains or applications where C/C++ remain preferable? Many exist—but are there tasks Rust fundamentally cannot handle or is a weak choice?
Undefined Behavior in C and C++ (2024)
171–180 of 234 posts
Re: Undefined Behavior in C and C++ (2024)
#172Earlier quoted context omitted.
Do you just meant an attempt to include a file path that couldn't be found? That's not a correct usage of the term "program" – that refers to the binary output of the compilation process, whereas you're taking about the source files that are the input to the compilation. That sounds a bit pedantic but I really didn't understand what you meant. I just checked, and if you attempt to include a file that cannot be found…
Yes; we are more interested in the other case: it happens to be found. What are the requirements then?
Re: Undefined Behavior in C and C++ (2024)
#173Earlier quoted context omitted.
I think we are slowly getting closer to the crux of the matter. Are you saying that it's a problem to include files from a library since they are "not in our program"? What does that phrase actually mean? What is the bounds of "our program" anyway? Couldn't it be the set {main.c, winkle.h}
> What is the bounds of our program? N3220: 5.1.1.1 Program Structure A C program is not required to be translated in its entirety at the same time. The text of the program is kept in units called source files, (or preprocessing files) in this document. A source file together with all the headers and source files included via the preprocessing directive #include is known as a preprocessing translation unit. After pre…
Your question about an include file that isn't part of the program just doesn't make any sense.
(Technically it says that those files together make up the "program text". As my other comment says, "program" is the binary output.)
Re: Undefined Behavior in C and C++ (2024)
#174Earlier quoted context omitted.
There is an incredible amount of C out there relative to how the sky basically isn't falling.
Ransomware attacks against hospitals and a dark extortion economy churning tens if not hundreds of billions of dollars a year in losses and waste. What would the "sky falling" look like to you? If you're expecting dramatic movie scenes like something out of Mr Robot, I'm afraid the reality is more mundane, just a never-ending series of basic programming errors that turn into remote code execution exploits because of…
Vulnerabilities to ransomware (and other forms of malware) can be perpetrated without a single bad pointer being dereferenced.
For instance, a memory-safe e-mail program can automatically open an attachment, and the memory-safe application which handles the attachment can blindly run code embedded in the document in a leaky sandbox.
There is an incredible amount of infrastructure out there that depends on C. Embedded devices, mobile devices, desktops, servers. Network stacks, telephony stacks, storage, you name it. Encryption, codecs, ...
Sky is falling would mean all of it would be falling down so badly that, for instance, you would have about a 50% chance of connecting a server that is more than four hops away.
Re: Undefined Behavior in C and C++ (2024)
#175Earlier quoted context omitted.
Yes; we are more interested in the other case: it happens to be found. What are the requirements then?
I don't get your point then. If the file is found then there is no undefined behaviour in the process of the file being included. There might be undefined behaviour in the overall translation unit after the text has been substituted in, but that's nothing to do with the preprocessor.
Correct; but processing doesn't stop there.
> There might be undefined behaviour in the overall translation unit
But what does that mean; how do you infer that there might be undefined behavior?
Does ISO C define the behavior, or does it not?
ISO C has nothing to say about what is in #include if such a header is found and didn't come from the program.
Without having anything to say about what is in it, if it is found at all, ISO C cannot be giving a definition of behavior of the tokens that are substituted for that #include.
Re: Undefined Behavior in C and C++ (2024)
#176Earlier quoted context omitted.
> What is the bounds of our program? N3220: 5.1.1.1 Program Structure A C program is not required to be translated in its entirety at the same time. The text of the program is kept in units called source files, (or preprocessing files) in this document. A source file together with all the headers and source files included via the preprocessing directive #include is known as a preprocessing translation unit. After pre…
The bit of the standard that you've quoted says that the program consists of all files that are compiled into it, including all files that are found by the #include directive. So, if does successfully resolve to something, then it must be part of the program by definition because that's what "the program" means. Your question about an include file that isn't part of the program just doesn't make any sense. (Technical…
So what I mean is that no file matching has been presented as part of the external file set given to the implementation for processsing.
I agree that if such a file is found by the implementation it becomes part of the program, as makes sese and as that word is defined by ISO C, so it is not right terminology to say that the file is not part of the program, yet may be found.
If the inclusion is successful, though, the content of that portion of that program is not defined by ISO C.
Re: Undefined Behavior in C and C++ (2024)
#177Earlier quoted context omitted.
The previous language might cause a C compiler developer to get very confused because it seems as though they can choose something else but what it is isn't specified, but almost invariably eventually they'll realise oh, it's just badly worded and didn't mean "should" there. It's like one of those tricky self-referential parlor box statements. "The statement on this box is not true"? Thanks I guess. But that's a game…
Most of the "ghosts" are indeed just cleaning up the wording. But compiler writers historically often used any excuse that the standard is not clear to justify aggressive optimization. This starts with an overreaching interpretation of UB itself, to wacky concepts such as time-travel, wobbly numbers, incorrect implementation of aliasing (e.g. still in clang), and pointer-to-integer round trips.
One huge thing they have on their side is that their implementation is concrete. Whatever it is that, say, GCC does is de facto actually a thing a compiler can do. The standards bodies (and WG21 has been worse by some margin, but they're both guilty) may standardize anything, but concretely the compiler can only implement some things. "Just do X" where X isn't practical works fine on paper but is not implementable. This was the fate of the Consume ordering. Consume/ Release works fine on paper, you "just" need to have whole program analysis to implement it. Well of course that's not practical so it's not implemented.
Re: Undefined Behavior in C and C++ (2024)
#178Earlier quoted context omitted.
I fully agree with your analysis but compilers writers did think the could bend the rules, hence it was necessary to clarify that pointer-to-integer casts do work as intended. This still not in ISO C 23 btw because some compiler vendors did argue against it. But it is a TS now. If you are, please file bugs against your compilers.
Do you fully agree? I finally went and read n3005.pdf. The important item there is that a cast to integer exposes the pointer and now the compiler must be conservative and assume that the pointed object might be changed via non trackable pointers. This seems quite a reasonable compromise to make existing code work without affecting the vast majority of objects whose address is never cast to an integer. But ncruces wa…
Re: Undefined Behavior in C and C++ (2024)
#179Earlier quoted context omitted.
Sorry, maybe I misread your comment. There are certainly languages easier to learn than C, but I would not say C++ or Rust fall into this category. At the same time, I find C compilation extremely fast exactly because of headers. In C you can split interface and implementation cleanly between header and c-file and this enables efficient incremental builds. In C++ most of the implementation is in headers, and all the…
> I find C compilation extremely fast exactly because of headers. The header model is one of the parts that makes compiling C slower than it could be. This doesn't mean that it is slow, but it's fast in spite of headers, not because of them. > In C you can split interface and implementation cleanly between header and c-file and this enables efficient incremental builds. That's not what does, it is the ability to prod…
I am not sure how it works in Rust as you need to monomorphize a lot of things, which come from other crates. It seems this would inevitably entangle the compilations.
Re: Undefined Behavior in C and C++ (2024)
#180Earlier quoted context omitted.
This isn’t the reason why the UB is in the spec in the first place. The spec left stuff undefined to begin with because of lack of consensus over what it should do. For example the reason why 2s complement took so long is because of some machine that ran C that still existed that was 1s complement. > The reason is that if you compile with flags that make it defined, you lose a few percentage points of performance (pr…
> For example the reason why 2s complement took so long is because of some machine that ran C that still existed that was 1s complement. You're misunderstanding me: as of C++20, there is no other representation in C++ for signed integers other than two's complement (no signed ones' complement, no signed magnitude, nothing else), but signed overflow is still UB. It's not because of obscure machines or hardware, such h…
I know that this is misguided based on my own perf tests and others’ perf tests.
Also, it’s wrong to say flat out that UB on signed ints is somehow necessary for perf when even a simple perf test shows that it just doesn’t matter, and the optimization it enables is quite obscure.