6

I know that the compiler may add some padding bytes in a struct. But is it possible, when the compiler sees that we never read from a variable inside a struct, that the struct will have a smaller size than the total size of the members?

struct Foo_T
{
  int a;
  intmax_t b;
};


void bar(void)
{
  struct Foo_T foo;
  foo.a=rand();
  someFunction(foo.a);
  //i never access foo.b, only foo.a
  if(sizeof(foo)< sizeof(int)+sizeof(intmax_t))
    {
      //is it possible that we can end here?
    }
}
chrisaycock
  • 36,470
  • 14
  • 88
  • 125
  • 3
    While it's true that a compiler can add some padding, and also do quite a lot of optimizations, I don't think it is allowed to remove members of a structure. It is also a very hard thing to deduce, especially if you pass the structure to external functions. – Some programmer dude Nov 21 '16 at 14:57
  • Read this useful topic : http://stackoverflow.com/questions/9486364/why-cant-c-compilers-rearrange-struct-members-to-eliminate-alignment-padding – Fefux Nov 21 '16 at 15:00
  • in C++ the compiler an empty base can't have size 0, however in derived classes the empty base can be leaved out, resulting in a child class size smaller than total size of its base and its own data – phuclv Nov 21 '16 at 15:58

4 Answers4

7

No, this is prohibited by the C standard. In C11, section 6.7.2.1 contains this statement:

15 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. [... ] There may be unnamed padding within a structure object, but not at its beginning.

Removing members of a struct would violate the requirement that the members have addresses that increase in the order in which they are declared.

Sam Holloway
  • 1,999
  • 15
  • 14
  • This just says that the members have to be allocated in the order they are declared. If some compiler would remove the last item of a struct, as in the case here, it wouldn't violate the cited text. The relevant part is rather found early on in the standard, where it describes the fundamental behavior of the "abstract machine" and what optimizations that are allowed. – Lundin Nov 21 '16 at 15:56
  • If you never access some member of the struct, how would you know that the requirement is violated? It wouldn't affect the observable behavior of the code and thus would be prefectly legal under "as if" rule. – AnT stands with Russia Nov 22 '16 at 00:29
3

No it isn't possible. When you take sizeof(foo) you expect to get at least sizeof(int) + sizeof(intmax_t). If the compiler would have given you a lesser size, it would have incorrectly affected the behavior of the program, which isn't allowed.

Suppose that you put the last member there as a place-holder "dummy", to guarantee that a reserved hardware register isn't used, or to ensure correct alignment. If the compiler would remove such a member, it would have broken the program.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

If a structure is declared in an automatic or static variable and neither the structure nor any part thereof has its address taken and used in any way the compiler doesn't 100% understand, a compiler may be able to change the layout of the structure if all code that uses the structure is adjusted accordingly. What's important is that there be no way that code can determine if a compiler does such a thing except by using mechanisms outside the language (e.g. viewing the memory layout with a debugger, or accessing areas of memory which have no defined use).

supercat
  • 77,689
  • 9
  • 166
  • 211
0

Absolutely not.

How should any compiler be able to anticipate you intend to write tomorrow? The fact that all the current source code does not use that element is in no way a guarantee that there will never be source code trying to access that part of the struct.

GhostCat
  • 137,827
  • 25
  • 176
  • 248