Earlier quoted context omitted.
can we just do `if(*ptr == NULL) return;` ?
If «ptr» is not a valid pointer, an attempt to dereference it (i.e. *ptr) will most assuredly crash the process with a SIGSEGV.
Defer: Resource cleanup in C with GCCs magic
71–80 of 99 posts
Re: Defer: Resource cleanup in C with GCCs magic
#72Re: Defer: Resource cleanup in C with GCCs magic
#73Re: Defer: Resource cleanup in C with GCCs magic
#74Earlier quoted context omitted.
C has had designated initializers since C99, if you want you can initialise every struct field at once.
I encourage you to read ( at least ) this section of this blog before making simplistic suggestions: https://thephd.dev/just-put-raii-in-c-bro-please-bro-just-on... How do you mandate initialization, handle copies, move objects, prevent double frees? What's RAII without any of that?
You pick C because you want a language that doesn't require a variable to be initialised before mutably referencing it, and you write your defer statements or "destructors" defensively, expecting that a variable could be in any state when it comes time to dispose of it.
Or if you find that unacceptable, you accept that C isn't the language you want. There's many other choices available.
Re: Defer: Resource cleanup in C with GCCs magic
#75Earlier quoted context omitted.
A zero (0, not NULL!) pointer is a valid pointer in C/C++. It is not a UB, and it means one simple thing: «give me the contents of a memory cell (a byte, a word, a long word etc) at the address of 0». Old hardware designs used the address of 0 to store a jump address of the system boot-up sequence (i.e. firmware), and I personally wrote the code in C to inspect / use it in the unpriviledged hardware mode. The prevail…
> it means one simple thing: «give me the contents of a memory cell (a byte, a word, a long word etc) at the address of 0» Well… sometimes. If you set a pointer to literal 0, you do not actually make that pointer point to address zero, from the C language's point of view. No, you are then setting it to be the null pointer. (c99 6.3.2.3 paragraph 3) Now, what is the bit value of a null pointer? That's undefined. So ho…
/* -O2 -std=c23 -Wall -fno-inline-functions */
int *ptr0 = 0;
int *ptr0p = (int *)0;
int
main ()
{
return *ptr0 | *ptr0p;
}
Head over to godbolt, compile it, and check the code. Zero compilation warnings, and the compiler duly obliges to generate the code that accesses a memory cell at the address 0x0 and all architectures that godbolt supports (ARM, RISC-V, SPARC64, POWER64, TI, S390 and others – with no exceptions).So if you run that code on a system before the MMU is activated or on a system without a MMU, «main» will return 0 on all systems[0] (if the memory is initialised with zeroes). You do have a point that some embedded systems[1] may have device registers mapped at 0, but that bears no relevance on the generated code – it will still attempt to read the 0th address.
You can also test the generated code in QEMU on an architecture of your choice in the «bare metal mode» (i.e. memory protection off) and observe that a read from 0 will give you 0 if the first memory page is filled with 0s.
> More info at https://stackoverflow.com/questions/63790813/allocating-addr...
You are most assuredly conflating a pointer to 0 dereferencing with the memory protection/virtual memory management system, and the explanation is in the first answer. It is Linux that implements a kernel-level check in mmap(2) on the address to mmap into, not the hardware. It is a Linux-specific quirk, and other UNIXes will allow the mmap to 0 to proceed but reading from 0 will still yield a SIGSEGV due to memory protection being in use.
> MMU is not the only way memory becomes magic. In fact, it's probably the LEAST of the magic memory mapping that can happen.
MMU is not magic. It is a simple and very efficient design that works in concert with the microarchitecture it has been implemented for – CPU traps, memory page descriptors and tables.
> I mean… you're just wrong. I'm not conflating unrelated things. I'm correcting multiple unrelated mis-statements you made.
Respectfully, so far I am yet to see a single compelling argument or tangible piece of evidence to support the claims you have espoused. I have provided a few very concrete and specific examples as supporting evidence, but I am not seeing the same on your side.
[0] The only exception that does not initialiase memory with zeroes that I am aware of is AIX (but not POWER/PowerPC that it runs on!) – the AIX VMM initialises a new memory page upon allocation with 0xdeadbeef to make unintialised pointers forcefully crash the process. Linux, *BSD's running on POWER/PowerPC do not do it, it is an AIX specific quirk.
[1] Again, embedded may have a nuance (subject to a specific hardware* implementation) as it is a commonplace in embedded systems to not* have a contiguous memory space and have holes in it, including the zeroeth address. It does not preclude the generated code to attempt to access 0, though, if the hardware supports it.
Re: Defer: Resource cleanup in C with GCCs magic
#76I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII. > If malloc fails and returns NULL, the cleanup function will still be called, and there’s no simple way to add a guard inside free_ptr. free(NULL) is a no-op, this is a non-issue. I don't know what's so hard about a single if statement anyway even if this were an issue.
Not having RAII is precisely the reason I prefer C over C++ or Rust. I WANT to be able to separate allocation from initialization. I'm currently working with Arduino code and the API is a mess. Everything has a second set of manual constructor/destructor, which bypasses type-safety entirely. All only to shoehorn having existing, but uninitialized objects into C++.
Usually Arduino code is written by hobbyist that give zero care about "clean and abstraction".
Re: Defer: Resource cleanup in C with GCCs magic
#77I don't understand why people insist on simulating a poor substitute for RAII with a feature that is itself almost decent RAII. > If malloc fails and returns NULL, the cleanup function will still be called, and there’s no simple way to add a guard inside free_ptr. free(NULL) is a no-op, this is a non-issue. I don't know what's so hard about a single if statement anyway even if this were an issue.
Not having RAII is precisely the reason I prefer C over C++ or Rust. I WANT to be able to separate allocation from initialization. I'm currently working with Arduino code and the API is a mess. Everything has a second set of manual constructor/destructor, which bypasses type-safety entirely. All only to shoehorn having existing, but uninitialized objects into C++.
Re: Defer: Resource cleanup in C with GCCs magic
#78Earlier quoted context omitted.
Not having RAII is precisely the reason I prefer C over C++ or Rust. I WANT to be able to separate allocation from initialization. I'm currently working with Arduino code and the API is a mess. Everything has a second set of manual constructor/destructor, which bypasses type-safety entirely. All only to shoehorn having existing, but uninitialized objects into C++.
>Arduino code Usually Arduino code is written by hobbyist that give zero care about "clean and abstraction".
Re: Defer: Resource cleanup in C with GCCs magic
#79Earlier quoted context omitted.
> Just use C++, it's its main feature on top of C. If you want to and/or can, then go ahead. This is for those people who either don't want to, or can't, use C++. Are you suggesting only use C++ over C in all situations?
Yes.
> Yes.
You cannot imagine any situation where that proposal is a non-starter? Or a deal-breaker?