sizeof(void) == 1

August 20th, 2007

Наткнулся на забавную вещь. Вот такой код спокойно компилируется GCC (версия 3.4.2 (mingw-special)):

#include <stdio.h>

int main()
{
    void* ptr;

    printf("sizeof(void): %d\\n", sizeof(void));

    ptr = 0;
    printf("before increment: %p\\n", ptr);
    ptr += 1;
    printf("after increment: %p\\n", ptr);

    return 0;
}

-Wall не генерирует никаких предупреждений. После запуска выдаёт следующее:

sizeof(void): 1
before increment: 00000000
after increment: 00000001

Т.е. sizeof(void) равен единице и инкремент void* указателя работает также как для char*. Visual C++ 2005 на этот код говорит:

rabbit.c(7) : warning C4034: sizeof returns 0
rabbit.c(11) : error C2036: 'void *' : unknown size

,

  1. eisernWolf
    August 20th, 2007 at 22:00 | #1

    CPP - это сплошной UB.

  2. Bacek
    August 20th, 2007 at 23:50 | #2

    Ветка gcc 3.4 выпущена в 2005 году. Много воды утекло с тех пор…

    [vasily@waters:~]$ cat > t.cc
    #include

    int main()
    {
    void* ptr;

    printf(”sizeof(void): %d\n”, sizeof(void));

    ptr = 0;
    printf(”before increment: %p\n”, ptr);
    ptr += 1;
    printf(”after increment: %p\n”, ptr);

    return 0;
    }

    [vasily@waters:~]$ gcc t.cc
    t.cc: In function ‘int main()’:
    t.cc:7: error: invalid application of ‘sizeof’ to a void type
    t.cc:11: error: pointer of type ‘void *’ used in arithmetic

    [vasily@waters:~]$ gcc –version
    gcc (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)
    Copyright (C) 2006 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  3. Bacek
    August 20th, 2007 at 23:51 | #3

    Не, соврал. В 2004-м…

  4. Bacek
    August 21st, 2007 at 00:31 | #4

    Не поленился таки. Взял из заначки gcc 3.2.

    [vasily@hyatt:~]$ gcc32 t.cc
    t.cc: In function `int main()’:
    t.cc:7: ISO C++ forbids applying `sizeof’ to type `void’ which is an incomplete
    type
    t.cc:11: pointer of type `void *’ used in arithmetic
    [vasily@hyatt:~]$ gcc32 –version
    gcc32 (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-47.fc4)
    Copyright (C) 2002 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    Это в mingw чего-то поломали.

  5. Bacek
    August 21st, 2007 at 03:36 | #5

    Ну и на последок: если компилировать этот код как “pure C”, а не C++, то действительно никаких предупреждений не выдаётся. Но против этого есть -pedantic.

  6. August 21st, 2007 at 08:02 | #6

    Интересно. :-)

    Ну и на последок: если компилировать этот код как “pure C”, а не C++, то действительно никаких предупреждений не выдаётся. Но против этого есть -pedantic.

    Да, с -predantic выдаются предупреждения:

    rabbit.c: In function `main':
    rabbit.c:7: warning: invalid application of `sizeof' to a void type
    rabbit.c:11: warning: pointer of type `void *' used in arithmetic
  7. Eugene Golushkov
    August 22nd, 2007 at 01:19 | #7

    GCC вообще довольно глючный компилятор. Это я говорю ответственно, так как он - системный компилятор под Mac OS X, и избежать его использования я не могу. Вот эта вариация

    $ gcc –version
    powerpc-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)
    Copyright (C) 2005 Free Software Foundation, Inc.

    имеет замечательный баг - static_cast теряет модификаторы const, что приводит к проблемам при выборе перегруженных функций и инстанциации шаблонов. Причем проблема появилась в версии 4.0, в версии 3.3 ее нет.

  8. August 23rd, 2007 at 14:35 | #8

    откуда такая склонность к мазохизму? что мешает использовать 3.4.6 или хотя бы 4.2.1?

    • August 23rd, 2007 at 23:02 | #9

      Именно эту версию GCC из MinGW автоматический инсталлятор предлагает в качестве current. А 4.x у них всё еще числится бетой.

  9. August 24th, 2007 at 02:46 | #10

    А 4.x у них всё еще числится бетой.

    так реально и есть. версиями gcc x.0.x/x.1.x можно пользоваться разве что для тестов. я вон с 2.95 переходил сразу на 3.3.1, потому что всё предыдущее из 3.* собирало мои проекты с ошибками. по этой же причине не было и официальных mingw сборок 4-ки до версии 4.2.1. потому как кто очень хочет — соберёт сам, а остальные только зафлудят рассылку репортом багов. да и 4.2.1 — не чистая версия, а содержит патчи их 4.3.0.

    • August 24th, 2007 at 09:00 | #11

       

      потому как кто очень хочет — соберёт сам

      Из “соберет себе сам” не получится бета только при условии, что сами разработчики объявили данную версию исходников “stable”. В случае MinGW последняя стабильная версия 3.4.2. А 4.2.1 - бета, и самостоятельная сборка этого обстоятельства не изменяет.

  1. August 20th, 2007 at 10:29 | #1