Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Empty structs are supported in clang; I think it's a GCC extension to C. This program:

  #include <stdio.h>
  
  typedef struct {} unit;
  
  static unit f(unit *p)
  {
      return (unit){};
  }
  
  static void g(unit u)
  {
  }
  
  int main()
  {
      unit a = {}, b = {};
      a = b;
      f(&a);
      g(b);
      printf("a is at %lx, b is at %lx, "
              "sizeof unit is %d\n",
              (unsigned long)&a, (unsigned long)&b,
              (int)sizeof(unit));
      return 0;
  }
compiles without complaints on my cellphone and produces the output:

a is at 7ffb39805b, b is at 7ffb39805a, sizeof unit is 0

So you can declare empty structs as variables, return them, assign them, pass them as parameters, take their addresses, create them in struct literals, and dereference pointers to them. clang is assigning different addresses to different empty-struct local variables, but presumably in an array all of them would have the same address, unlike in C++.

I wouldn't be confident that you could malloc them, and I wouldn't be surprised if passing them by value uncovered compiler divergences in the interpretation of the ABI. (I spent most of last night tracking down a bug due to LuaJIT/GCC ABI differences in the implementation of parameter passing.)



> Empty structs are supported in clang; I think it's a GCC extension to C.

Indeed. See https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Empty-Structur....

That page also says “In C++, empty structures are part of the language”, and “G++ treats empty structures as if they had a single member of type char”. I think that means the size of empty structs differs between GCC C and GCC C++.


Thanks! Yes, C++ requires all objects to have a nonzero size.

In GCC these two variables get the same address; also true in clang with -O.


Why couldn't you malloc them? Malloc doesn't care about types, it just wants the number of bytes, and 0 is a perfectly valid value to pass to malloc. Now, it's unspecified whether malloc will give you back a pointer distinct from all other non-freed allocated blocks or NULL, but if you don't rely on address as identity that is irrelevant.


You're right, in the standard it's implementation-defined. I mistakenly thought malloc(0) was undefined. That said, it's probably not the best-tested code path in the system library.


And correspondingly calling free() on the returned value is also unlikely to be particularly well tested.


Well, unless it's NULL. I'm pretty sure that people call free(0) a lot.


I mean, these are literally all special values that are explicitly called out in all the relevant standards (both ISO C and POSIX). Anyone who is competent and is writing tests for libc would surely cover that.


Probably malloc(0) is not completely untested, yes. But it's unlikely to be regularly executed by applications.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: