0

I have a question regarding the size of data in a const void*. In the code below, the output of the first printf is 6 while the output of the second printf is 3. Please help, I cannot find where the problem comes from. Thank you in advance

#define TEST "\x00\x01\x02\x03\x04\x05"

#include <stdio.h>

static void function(const void* c);

int main (void) {

    printf("TEST: %d\n",sizeof(TEST) -1);
    function(TEST);

    return 0;
}

static void function(const void* c) {
    printf("TEST: %d\n",sizeof(c) -1);
}

2 Answers2

5

In the first case, sizeof(TEST) is the size of the string literal, which is an array large enough to contain all the characters plus the terminator - in this case, 7 bytes.

In the second case, sizeof(c) is the size of a pointer - 4 bytes, on your 32-bit platform.

In general, there is no way to tell the size of an array given just a pointer to it. If it pointed to a C-style terminated string, you can measure the length with strlen(c). However, in this case, it contains a null character, so there's no way to determine the length.

In C++, you could use a template, rather than sizeof, to get the size of an array:

template<typename T, size_t N> size_t array_size(T(&)[N]) {return N;}

This has the advantage that you'll get a compile-time error, rather than an unexpected runtime result, if you accidentally apply it to a pointer instead of an array.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • I tries with strlen(c) but I get 0 for the size. Can you give more details please. Thank you! – user3821117 Jul 09 '14 at 21:11
  • @user3821117: Your string starts with a null character, so it will appear to have zero length. Since it's not a valid C-style string, there's no way to find the length. – Mike Seymour Jul 10 '14 at 14:05
1

The sizeof operator return the number of bytes of either a type name or an expression with respect to sizeof(char). Has the following syntax:

sizeof unary-expression 
sizeof ( type-name ) 

If it's a unary-expression and it's a string literal like you sizeof(TEST) it does return the count of bytes in this string, including null-byte-terminattor. But if it's a expression like 2*p which has int resulting type, the expression is evaluated at compile-time (without any side-effect) and the size of resulting-type (int) is returned, as sizeof(int)

Or if it's type-name like in your sizeof(c) it return the platform-independent number of bytes of this type. e.g, sizeof(int) on 32-bit machine is 4 bytes.

The Mask
  • 17,007
  • 37
  • 111
  • 185
  • `sizeof` returns the size in number of `char`s – clcto Jul 09 '14 at 15:40
  • @clcto, `sizeof` is always measured in bytes. `char` is one byte. – chris Jul 09 '14 at 15:41
  • @chris no `sizeof(char)` is defined as 1, while the number of bytes in a char is implementation defined – clcto Jul 09 '14 at 15:42
  • 1
    @clcto: What do you mean? In C and C++, a `char` is one byte, by definition. – Mike Seymour Jul 09 '14 at 15:44
  • @MikeSeymour so a byte isn't defined as 8 bits? – clcto Jul 09 '14 at 15:46
  • @clcto, C: `The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type.` C++: `The sizeof operator yields the number of bytes in the object representation of its operand.` And a byte is `CHAR_BIT` bits. – chris Jul 09 '14 at 15:46
  • I edited a bit my answer to try make it more clear. – The Mask Jul 09 '14 at 15:46
  • @MikeSeymour: check out this http://stackoverflow.com/questions/2098149/what-platforms-have-something-other-than-8-bit-char – The Mask Jul 09 '14 at 15:47
  • 1
    @clcto: "so a byte isn't defined as 8 bits?" No. A byte is defined as the smallest addressable object, with `CHAR_BIT` bits. It's 8 bits on most popular platforms, but there are platforms (e.g. DSPs and old-school mainframes) with differently sized bytes. (I once had to write string-handling functions on a platform with 24-bit bytes, which I won't recommend if you're looking for fun.) – Mike Seymour Jul 09 '14 at 15:48
  • @MikeSeymour, Did you have three characters per `char`? I can't see that being too fun. – chris Jul 09 '14 at 16:03
  • @chris: Yes: not enough RAM to waste on one word per character. Better still, the compiler writer didn't agree with the C library writer on which ordering to use, so string literals had to be written `"leH\0ol"` to be compatible with the library. – Mike Seymour Jul 09 '14 at 16:13
  • @MikeSeymour, Oh man. – chris Jul 09 '14 at 16:41