Earlier quoted context omitted.
IIRC this is valid in C99: void foo(size_t n) { int arr[n]; … }
How do you think it works? Does the compiler generate some kind of stack alloc? Stupid question: Does that mean a huge value for 'n' can cause stack overflow at runtime? I recall that threads normally get a fixed size stack size, e.g., 1MB.
Everything I wish I knew when learning C
371–380 of 401 posts
Re: Everything I wish I knew when learning C
#372Earlier quoted context omitted.
...Why is the compiler reordering so much? Look. I get it, clever compilers (I guess) make everyone happy, but are absolute garbage for facilitating program understanding. I wonder if we are shooting ourselves in the foot with all this invisible optimization.
People like fast code.
Re: Everything I wish I knew when learning C
#373Earlier quoted context omitted.
They’re not pointers. sizeof a == 4*sizeof(int) , not sizeof(int*) .
They're pointers, just weird ones. The compiler knows it's an array, so it gives the result of the actual amount of space it takes up. If you passed it into a function, and used the sizeof operator in the function, it'd give `sizeof(int *)`. Because sizeof is a compile-time operation, so the compiler still knows that info for your example.
Re: Everything I wish I knew when learning C
#374Re: Everything I wish I knew when learning C
#375Earlier 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.
How this might happen is that one branch of your program may have unconditional undefined behavior, which can be detected at the check itself. This would let a compiler elide the entire branch, even side effects that would typically run.
Re: Everything I wish I knew when learning C
#376Earlier quoted context omitted.
fopen will/should fail on windows with the unix path syntax. The reason it's indeterminate is because some stdc lib vendors will do path translation on Windows, some won't. I believe cygwin does (because it's by definition a unix-on-windows), but I'm pretty sure the normal stdclib vendors on windows do not. I'm almost positive that MacOS (before MacOS X) will fail with unix path separators, since path separators are…
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.
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...
Re: Everything I wish I knew when learning C
#377Earlier quoted context omitted.
> C is often [correctly, but misleadingly] advertised as a cross-platform assembly language, that will compile to the assembly that the author would expect. Because that's what it is. What they don't tell you is that the most heavily-developed two (or more) compilers for it (which you might otherwise assume meant the two best compilers), are malware[0] that actively seek out excuses to inject security vulnerabilities…
Nice way to put down the amazing work of compiler authors. It's not malware you just don't understand how to use it. If you don't want the compilers to do crazy optimisations turn down the optimisation level. If you want then to check for things like null pointers or integer overflow or array bounds at runtime then just turn on the sanitizers those compiler writers kindly provided to you. You just want all of it: fas…
I specificly don't want them to check for those things; that is the fucking problem in the first place! When I write:
x = *p;
I want it compiled to a damn memory access. If I meant: x = *p; __builtin_assume_non_null(p);
I'd have damn well written that.Re: Everything I wish I knew when learning C
#378Earlier quoted context omitted.
> I wrote: > > Integer division is a slow operation, and under the rules of C, it has no side effects. Yes, you did, and while that's a reasonable approximation in some contexts, it is false in the general case, since division by zero has a side effect in the form of invoking undefined behaviour. (Arguably that means it has every possible side effect, but that's more of a philosophical issue. In practice it has vario…
> it is false in the general case, since division by zero has a side effect in the form of invoking undefined behaviour. They were careful to say “under the rules of C,” the rules define the behaviour of C. On the other hand, undefined behaviour is outside the rules, so I think they’re correct in what they’re saying. The problem for me is that the compiler is not obliged to check that the code is following the rules.…
Yes, and under the rules of C, division by zero has a side effect, namely invoking undefined behaviour.
> The problem for me is that the compiler is not obliged to check that the code is following the rules.
That part's actually fine (annoying, but ultimately a reasonable consequence of the "rules the compiler can check" issue); the real(ly bad and insidious) problem is that when the compiler does check that the code is following the rules, it's allowed to do it in deliberately backward way that uses any case of not following the rules as a excuse to break unrelated code.
Re: Everything I wish I knew when learning C
#379I 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…
Another weird property about C arrays is that &arr == arr. The reference of an array is the pointer to the first element, which is what `arr` itself decays to. If arr was a pointer, &arr != arr.
Re: Everything I wish I knew when learning C
#380Earlier quoted context omitted.
> 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. IIRC C has an informal guarantee that no primitive syntax will ever cause the CPU to do more than O(1) work at runtime. Assignment is always O(1), and therefore assignment is limited to scalars. If you need assignment that might do O(N) work, you need to call a stdlib f…
> IIRC C has an informal guarantee that no primitive syntax will ever cause the CPU to do more than O(1) work at runtime. How about CPUs that have no, say, division instruction, so it has to be emulated with a loop?