By Lakshmi


2009-11-03 09:30:11 8 Comments

What would this statement yield?

void *p = malloc(sizeof(void));

Edit: An extension to the question.

If sizeof(void) yields 1 in GCC compiler, then 1 byte of memory is allocated and the pointer p points to that byte and would p++ be incremented to 0x2346? Suppose p was 0x2345. I am talking about p and not *p.

10 comments

@Keith Thompson 2015-02-01 03:17:20

void has no size. In both C and C++, the expression sizeof (void) is invalid.

In C, quoting N1570 6.5.3.4 paragraph 1:

The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member.

(N1570 is a draft of the 2011 ISO C standard.)

void is an incomplete type. This paragraph is a constraint, meaning that any conforming C compiler must diagnose any violation of it. (The diagnostic message may be a non-fatal warning.)

The C++ 11 standard has very similar wording. Both editions were published after this question was asked, but the rules go back to the 1989 ANSI C standard and the earliest C++ standards. In fact, the rule that void is an incomplete type to which sizeof may not be applied goes back exactly as far as the introduction of void into the language.

gcc has an extension that treats sizeof (void) as 1. gcc is not a conforming C compiler by default, so in its default mode it doesn't warn about sizeof (void). Extensions like this are permitted even for fully conforming C compilers, but the diagnostic is still required.

@Grzegorz Szpetkowski 2015-02-21 11:51:21

I guess that they allowed sizeof(void) == 1 for consistency with pointer arithmetic on void pointer, that is also a gcc extension. Citing from their documentation: A consequence of this is that sizeof is also allowed on void and on function types, and returns 1.. But still diagnostic message should be present by default for C as Standard requires it.

@Keith Thompson 2017-09-07 23:59:59

@GrzegorzSzpetkowski: (Replying a couple of years later.) Yes, the standard requires a diagnostic, but gcc is not a conforming C compiler by default. Logically, the C standard imposes no requirements on implementations that do not claim to conform to it. gcc can be made to be (very nearly) conforming with the right command-line options, such as -std=c11 -pedantic. With such options, it does issue the required diagnostic.

@reko_t 2009-11-03 09:31:42

The type void has no size; that would be a compilation error. For the same reason you can't do something like:

void n;

EDIT. To my surprise, doing sizeof(void) actually does compile in GNU C:

$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc -w - && ./a.out 
1

However, in C++ it does not:

$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc++ -w - && ./a.out 
<stdin>: In function 'int main()':
<stdin>:1: error: invalid application of 'sizeof' to a void type
<stdin>:1: error: 'printf' was not declared in this scope

@Jonathan Leffler 2009-11-03 09:37:07

But GCC has an option to treat 'sizeof(void) == sizeof(char)'...See -Wpointer-arith

@unixman83 2011-07-16 14:56:06

@Jon this is for fools from the early 80's who were just starting to learn how to program. Standards were not widely decided upon.

@Keith Thompson 2015-02-01 03:06:09

sizeof (void) is a constraint violation. A conforming C compiler (which gcc is not by default) must at least warn about it, and may (and IMHO should) reject it. Reference: N1570 6.5.3.4p1 (void is an incomplete type). It's been this way since the 1989 standard, which introduced void.

@Keith Thompson 2015-02-01 03:06:51

@unixman83: That doesn't make sense. void didn't exist before it was introduced by the 1989 ANSI C standard, the same standard that made sizeof (void) a constraint violation.

@kelin 2015-10-13 16:27:42

Sizeof void is compiled because you need it to work with void* pointers.

@kriss 2013-03-21 09:34:36

Most C++ compilers choosed to raise a compile error when trying to get sizeof(void).

When compiling C, gcc is not conforming and chose to define sizeof(void) as 1. It may look strange, but has a rationale. When you do pointer arithmetic adding or removing one unit means adding or removing the object pointed to size. Thus defining sizeof(void) as 1 helps defining void* as a pointer to byte (untyped memory address). Otherwise you would have surprising behaviors using pointer arithmetic like p+1 == p when p is void*. Such pointer arithmetic on void pointers is not allowed in c++ but works fine with when compiling C with gcc.

The standard recommended way would be to use char* for that kind of purpose (pointer to byte).

Another similar difference between C and C++ when using sizeof occurs when you defined an empty struct like:

struct Empty {
} empty;

Using gcc as my C compiler sizeof(empty) returns 0. Using g++ the same code will return 1.

I'm not sure what states both C and C++ standards on this point, but I believe defining the size of some empty structs/objects helps with reference management to avoid that two references to differing consecutive objects, the first one being empty, get the same address. If reference are implemented using hidden pointers as it is often done, ensuring different address will help comparing them.

But this is merely avoiding a surprising behavior (corner case comparison of references) by introduction another one (empty objects, even PODs consume at least 1 byte memory).

@Konrad Rudolph 2013-03-21 09:37:36

“C chose instead to define sizeof(void) as 1.” – No, that’s wrong. sizeof(void) is not defined in C, same as in C++. GCC simply is not conforming in this point, and pointer arithmetic on void pointers is simply not defined either – void* p; p++; is invalid. Even GCC will give you a warning when compiling with the -pedantic flag. And you are also wrong about the default behaviour of GCC for C++: by default this is treated as an error.

@kriss 2013-03-21 12:40:37

@Konrad: yes, I'm quite sure it was not true with older version of gcc, but up to date ones do as you say.

@Keith Thompson 2015-02-01 03:20:54

At least in C, an empty struct definition is a syntax error; gcc's support is an extension. They may be valid in C++; I'm not sure.

@user906752 2011-11-17 19:59:03

while sizeof(void) perhaps makes no sense in itself, it is important when you're doing any pointer math.

eg.

 void *p;
 while(...)
      p++;

If sizeof(void) is considered 1 then this will work. If sizeof(void) is considered 0 then you hit an infinite loop.

@James Roth 2013-09-13 17:05:50

The example code snippet is illegal in C and C++. Some compilers allow it anyway.

@Keith Thompson 2015-02-01 03:07:56

No, it's not important at all (though the authors of gcc apparently thought it was). If you want to do pointer arithmetic on byte pointers, use unsigned char*.

@ash 2019-10-23 23:45:04

@KeithThompson - even char is not guaranteed to be 1 byte. I have worked on a system that set it to 32 bits.

@Keith Thompson 2019-10-24 00:02:35

@ash: Yes, char is guaranteed to be 1 byte. If you've worked on a system with 32-bit char, then a byte on that system is 32 bits (CHAR_BIT == 32). That's how the C standard defines "byte". C standard, 6.5.3.4 paragraphs 2 and 4: "The sizeof operator yields the size (in bytes) of its operand. [...] When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1."

@ash 2019-10-29 18:57:56

When did C standard 6.5.3.4 come out? I worked on this system back in the mid 90's.

@user59634 2009-11-03 09:57:19

To the 2nd part of the question: Note that sizeof(void *)!= sizeof(void). On a 32-bit arch, sizeof(void *) is 4 bytes, so p++, would be set accordingly.The amount by which a pointer is incremented is dependent on the data it is pointing to. So, it will be increased by 1 byte.

@Lakshmi 2009-11-03 09:58:53

so p was pointing to 1 byte data since sizeof(void) gives 1 so p++ means p would be increment by 1 and not 4??

@user59634 2009-11-03 10:32:39

The amount by which a pointer is incremented is dependent on the data it is pointing to. So Yes.

@Technowise 2009-11-03 10:59:05

p is of void* (void pointer) type, not void. So it would be incremented by the size of void* type (which is usually 4 in 32 bit systems).

@Konrad Rudolph 2009-11-03 17:48:34

@Technowise: no. Any pointer of type T* is incremented by sizeof(T) (and not sizeof(T*), which would almost always be the same, except perhaps for function pointers) when it is incremented. The exception is of course void (and again the exception is when having the GCC extensions enabled).

@Keith Thompson 2015-02-01 03:09:47

@Amit: How did you conclude that the size of the data a void* pointer points to is 1 byte? sizeof (void) is a constraint violation. (A gcc extension treats it as 1.)

@Greg Hewgill 2009-11-03 09:33:27

In C, sizeof(void) == 1 in GCC, but this appears to depend on your compiler.

In C++, I get:

In function 'int main()':
Line 2: error: invalid application of 'sizeof' to a void type
compilation terminated due to -Wfatal-errors.

@Jonathan Leffler 2009-11-03 09:38:46

Only in GCC is sizeof(void) == 1; in the standard, it is undefined behaviour.

@Greg Hewgill 2009-11-03 09:48:31

Updated to add GCC specific note.

@Keith Thompson 2015-02-01 03:08:28

@JonathanLeffler: It's not merely undefined behavior. It's a constraint violation. N1570 6.5.3.4p1.

@pmg 2009-11-03 09:39:02

Taking the size of void is a GCC extension.

@hrnt 2009-11-03 09:35:35

If you are using GCC and you are not using compilation flags that remove compiler specific extensions, then sizeof(void) is 1. GCC has a nonstandard extension that does that.

In general, void is a incomplete type, and you cannot use sizeof for incomplete types.

@Josh Lee 2009-11-03 12:13:11

The option -Wpointer-arith is implied by -pedantic. I always used -pedantic. :)

@hrnt 2009-11-11 15:33:04

@jleedev Indeed, I also use -pedantic as much as I can. Unfortunately, though, some third party library headers make gcc -pedantic very sad :(

@user142019 2012-01-25 21:42:36

+1 Really, why does GCC have thousands of useless extensions?

@kriss 2014-11-26 15:00:32

@user142019: because they are usefull ? And helps getting a consistent backend model through different programming languages and hardware architecture.

@Aleksei Potov 2009-11-03 09:34:13

sizeof() cannot be applied to incomplete types. And void is incomplete type that cannot be completed.

@Konrad Rudolph 2009-11-03 09:33:44

Although void may stand in place for a type, it cannot actually hold a value. Therefore, it has no size in memory. Getting the size of a void isn’t defined.

A void pointer is simply a language construct meaning a pointer to untyped memory.

@kriss 2013-03-21 09:22:58

so what ? Shouldn't any empty struct also consume no size in memory and that should be a problem. Well actually I wonder, if empty structs are truly using 0 bytes in C++ (as is true in C) looks like sizeof returns 1 for them.

@Konrad Rudolph 2013-03-21 09:35:33

@kriss I’m not sure what you’re saying but as you’ve noticed yourself, empty structs do occupy memory for reasons of object identity.

@kriss 2013-03-21 12:39:16

indeed, but it was not true in C and using memory for empty objects feels evil.

Related Questions

Sponsored Content

39 Answered Questions

22 Answered Questions

[SOLVED] What is the "-->" operator in C++?

28 Answered Questions

17 Answered Questions

[SOLVED] How to allocate aligned memory only using the standard library?

  • 2008-10-22 23:23:41
  • JimDaniel
  • 170577 View
  • 408 Score
  • 17 Answer
  • Tags:   c memory-management

10 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite?

8 Answered Questions

[SOLVED] What is The Rule of Three?

10 Answered Questions

11 Answered Questions

[SOLVED] What does the explicit keyword mean?

2 Answered Questions

Sponsored Content