LINUX.ORG.RU

C, препроцессор и размер/выравнивание типов

 ,


0

4

Привет, ЛОР!

Добавляю поддержку кросс-компиляции в один проект, возникла такая проблема: нужно сделать сишный файлик с размером и выравниванием некоторых типов без запуска кода. Что я хочу получить:

#define SIZEOF_typename 4
#define ALIGNMENT_OF_typename 4
...

Запускать код при этом нельзя, потому что кросскомпиляция, смерть, жопа и сотона. Сейчас там это делается через автоконф (AC_CHECK_SIZEOF/ALIGNOF) и это не работает именно по этой причине. Что делать?

Про #define ALIGN_OF_X alignof(x) я в курсе, но проект древний и в нём есть вычисления через препроцессор, которые я пока не хочу трогать.

Ответ на: комментарий от hateyoufeel

Потому что это константное выражение

Cast operators in an integer constant expression shall only convert arithmetic types to integer types?

его можно записать в constexpr

#include <stddef.h>

struct S { int x; };

constexpr auto x = (size_t)(&((struct S*)0)->x);

clang:

<source>:5:16: error: constexpr variable 'x' must be initialized by a constant expression
    5 | constexpr auto x = (size_t)(&((struct S*)0)->x);
      |                ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:5:20: note: this conversion is not allowed in a constant expression
    5 | constexpr auto x = (size_t)(&((struct S*)0)->x);
      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

gcc:

<source>:5:20: error: 'constexpr' integer initializer is not an integer constant expression
    5 | constexpr auto x = (size_t)(&((struct S*)0)->x);
      |                    ^

https://godbolt.org/z/4oehGrG1j

Кастомный таргет со своей libc

freestanding-хедеры это часть кросс-компилятора

stddef.h тут пишем тоже мы

ССЗБ?

utf8nowhere ★★★★
()
Последнее исправление: utf8nowhere (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

stddef.h тут пишем тоже мы

Я бы сказал что к offsetof и прочим va_arg нужно относиться как к встроенным операторам/типам. Ну а то, что они макросы — «так исторически сложилось». Вообщим, считай что это «кишочки» компилятора, которые нужно использовать как данность, а не пытаться писать самому (если только сам компилятор тоже не пишешь, конечно))0)0 ). Думаю, так жить сразу станет легче))0)0

Вот тебе «на подумать»:

[/usr] user@host $ search stdarg.h
…
./lib/llvm-14/lib/clang/14.0.0/include/stdarg.h
./lib/llvm-11/lib/clang/11.1.0/include/stdarg.h
./lib/gcc/x86_64-linux-gnu/11/include/stdarg.h
./lib/gcc/x86_64-linux-gnu/12/include/stdarg.h
…

[/usr] user@host $ search stdio.h
…
./include/stdio.h
…

$ gcc -E -Wp,-v -xc /dev/null
…
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/11/include
 /usr/local/include
 /usr/include/x86_64-linux-gnu
 /usr/include
…

Вникай в моё послание тебе постарайся проанализировать и сделать выводы для себя)

utf8nowhere ★★★★
()
Ответ на: комментарий от utf8nowhere

Вообщим, считай что это «кишочки» компилятора, которые нужно использовать как данность, а не пытаться писать самому (если только сам компилятор тоже не пишешь, конечно))0)0 ). Думаю, так жить сразу станет легче))0)0

Это часть libc.

https://git.musl-libc.org/cgit/musl/tree/include/stddef.h

https://git.musl-libc.org/cgit/musl/tree/include/stdarg.h

То, что тащит с собой компилер, не везде выходит использовать.

Хотя опять же, тут не мой код изначально, и наличие этих заголовков – исторический артефакт. Возможно, их и правда стоит убрать.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

https://git.musl-libc.org/cgit/musl/tree/include/stddef.h

https://git.musl-libc.org/cgit/musl/tree/include/stdarg.h

Да я видел. PDCLib, например, тоже зачем-то имеет эти заголовочные файлы. Но хотя бы определяет #define offsetof( type, member ) _PDCLIB_offsetof( type, member ) (и т.п.), а _PDCLIB_offsetof предполагается определять в слое переностимости.

Ну и всё равно должны подхватиться компиляторные хедеры, если каталог с ними просматривается первым.

То, что тащит с собой компилер, не везде выходит использовать.

Я бы сказал что кривой [кросс-]компилятор стоит лечить/патчить на уровне этого [кросс-]компилятора, а в своей реализации libc предполагать что freestanding-хедеры уже есть. Такой подход выглядит идеологически (и неидеологически тоже) чище/надёжнее.

utf8nowhere ★★★★
()
Последнее исправление: utf8nowhere (всего исправлений: 1)