Live data from Hacker News

Everything I wish I knew when learning C

tmewett.com

381–390 of 401 posts

Re: Everything I wish I knew when learning C

#381
post #376
post #341

Earlier quoted context omitted.

It will work on Windows, since it inherits the behavior from MS-DOS. It's the shell on Windows (or MS-DOS) where it fails since the shell uses '/' to designate options, so when MS-DOS gained subdirectories (2.0) it used '\' as the file separator on the shell. The "kernel" will accept both. There even used to be an undefined (or underdefined) function in MS-DOS to switch the option character.

Apparently it's true. I wonder when this was implemented? Canonicalize separators "All forward slashes (/) are converted into the standard Windows separator, the back slash (\). If they are present, a series of slashes that follow the first two slashes are collapsed into a single slash." https://learn.microsoft.com/en-us/dotnet/standard/io/file-pa...

Since MS-DOS 2.0, released in October of 1983---39 years ago.

Re: Everything I wish I knew when learning C

#382
post #285

Earlier quoted context omitted.

> is there a situation where there's automatic storage but no stack? Yes. As a trivial example, some C interpreters use a different datastructure instead of a stack.

But the stack refers to the number of calling functions, stacked upon one another too? This is why its always stack, disregard the structure.. cause its a mirror of the program running, and the usual c program uses functions.

Well, the term is overloaded. C has recursion so an implementation needs something like a call stack, but you don't have to store it in a stack datastructure.

Re: Everything I wish I knew when learning C

#383
post #276

Earlier quoted context omitted.

It doesn't matter how it knows. The standard permits it to do that. The compiler authors will not accept your bug report.

If you truly believe so, then can you give an example of input-conditional UB causing unexpected observable behavior, before the input is actually read? This should be impossible, since otherwise the program would have incorrect behavior if a non-UB-producing input is given.

If it's provably input-conditional then of course it's impossible. But the C implementation does not have to obey the sequence point rules or perform observable effects in the correct order for invocations that contain UB, and it doesn't have to implement "possible" non-UB-containing invocations if you can't find them. E.g. if you write a program to search for a counterexample for something like the Collantz Conjecture, that loops trying successively higher numbers until it finds one and then exits, GCC may compile that into a program that exits immediately (since looping forever is, arguably, undefined behaviour) - there's a real example of a program that does this for Fermat's Last Theorem.

Re: Everything I wish I knew when learning C

#384

I like it, but the array details are a little bit off. An actual array does have a known size, that's why when given a real array `sizeof` can give the size of the array itself rather than the size of a pointer. There's no particular reason why C doesn't allow you to assign one array to another of the same length, it's largely just an arbitrary restriction. As you noted, it already has to be able to do this when assi…

Return pointer to array of 4 integers: int32_t (* bar(void))[4] { static int32_t u[4] = {1, 0, 1, 0}; return &u; } Return a pointer to a function taking a char: void f(char a) { // ... } void (* baz(void))(char) { return f; }

This is where you really want to start using typedefs.

Re: Everything I wish I knew when learning C

#385

Earlier quoted context omitted.

People like fast code.

In 2022, is there any other reasons to use C besides "fast code" or "codebase already written in C"?

"codebase already written in C" includes both "all the as yet unwrapped libraries" and "the OS interface".

Re: Everything I wish I knew when learning C

#386
post #85

Earlier quoted context omitted.

Completely agree - that's exactly why I wrote this. Some of things I wrote even seem super obvious but with no real authority you wonder whether or not this is "the way" to do things. If you ever want to get some practical experience, we'll help you out if you want to contribute to Brogue :)

Replying here hoping that you'll have a better chance of seeing it: thank you for maintaining Brogue. I've sung praises [0][1][2] for years about the quality of the Brogue codebase (and the game itself). [0] https://news.ycombinator.com/item?id=20560132 [1] https://news.ycombinator.com/item?id=19901128 [2] https://news.ycombinator.com/item?id=13594689

Thank you :) Though I should say, most of the code is by the original author Brian

Re: Everything I wish I knew when learning C

#387
post #202

The reason you use specific sizes for types (int8, int16, uint16, etc) is so you know how to read/write them when you move your data between platforms. x86 is little endian. ARM apparently can be configured to be either. In real code there should be readXXX and writeXXX functions that read/write data from disk/network and do the byte swapping in there. You could also just convert everything to JSON, but you're tradin…

> ARM apparently can be configured to be either. That's insane!!! TIL

Not really, it is very easy to do this in hardware.

Re: Everything I wish I knew when learning C

#389
post #383

Earlier quoted context omitted.

If you truly believe so, then can you give an example of input-conditional UB causing unexpected observable behavior, before the input is actually read? This should be impossible, since otherwise the program would have incorrect behavior if a non-UB-producing input is given.

If it's provably input-conditional then of course it's impossible. But the C implementation does not have to obey the sequence point rules or perform observable effects in the correct order for invocations that contain UB, and it doesn't have to implement "possible" non-UB-containing invocations if you can't find them. E.g. if you write a program to search for a counterexample for something like the Collantz Conjectu…

> If it's provably input-conditional then of course it's impossible.

My entire point pertains to programs with input-conditional UB: that is, programs for which there exists an input that makes it result in UB, and there also exists an input that makes it not result in UB. Arguably, it would be more difficult for the implementation to prove that input-dependent UB is unconditional: that every possible input results in UB, or that no possible input results in UB.

> But the C implementation does not have to obey the sequence point rules or perform observable effects in the correct order for invocations that contain UB

Indeed, the standard places no requirements on the observable effects of an execution that eventually results in UB at some point in the future. But if the UB is input-conditional, then a "good" execution and a "bad" execution are indistinguishable until the point that the input is entered. Therefore, the implementation is required to correctly perform all observable effects sequenced prior to the input being entered, since otherwise it would produce incorrect behavior on the "good" input.

> E.g. if you write a program to search for a counterexample for something like the Collantz Conjecture, that loops trying successively higher numbers until it finds one and then exits, GCC may compile that into a program that exits immediately (since looping forever is, arguably, undefined behaviour) - there's a real example of a program that does this for Fermat's Last Theorem.

That only works because the loop has no observable effects, and the standard says it's UB if it doesn't halt, so the compiler can assume it does nothing but halts. As noted on https://blog.regehr.org/archives/140, if you try to print the resulting values, then the compiler is actually required to run the loop to determine the results, either at compile time or runtime. (If it correctly proves at compile time that the loop is infinite, only then can it replace the program with one that does whatever.)

It's also irrelevant, since my point is about programs with input-conditional UB, but the FLT program has unconditional UB.

Re: Everything I wish I knew when learning C

#390

Earlier quoted context omitted.

People like fast code.

In 2022, is there any other reasons to use C besides "fast code" or "codebase already written in C"?

There isn't. Fast code is pretty important though to a lot of people while security isn't (games, renderers, various solvers, simulations etc.).

It's great C is available for that. If you're ok with slow use Java or whatever.

Post reply on HN