Подтвердить что ты не робот

Ли extern C с С++ избегает поведения undefined, который является законным в C, но не С++?

Если вы используете extern C с файлами С++, разрешает ли это определение поведения C undefined в С++?

blah.h

 extern "C"
 {
      struct x {
           int blah;
           char buf[];
      };

      char * get_buf(struct x * base);
      struct x * make_struct(int blah, int size);
 }

some_random.cpp

 #include "blah.h"

 ...

 x * data=make_struct(7, 12);
 std::strcpy(get_buf(data), "hello");

Используется ли определенное поведение в элементе C гибкого массива, определяется поведение при его использовании?

4b9b3361

Ответ 1

Элементы гибкого массива являются стандартной функцией C, начиная с стандарта 1999 года. Они не существуют в С++.

Ваш код недействителен С++. Обертка в extern "C" не меняет этого. Соответствующий компилятор С++ должен хотя бы предупредить об этом и, возможно, должен отклонить его.

Случается, что g++ реализует элементы гибкого массива C-стиля в качестве расширения для С++. Это совершенно законно (компиляторам разрешено реализовать расширения), но его использование не переносимо. Его поведение, как и любое расширение языка, определяется компилятором, а не языком.

Если вы скомпилируете его с помощью g++ -pedantic, вы получите предупреждение:

c.cpp:5:21: warning: ISO C++ forbids zero-size array ‘buf’ [-Wpedantic]
            char buf[];
                     ^

Если вы хотите использовать гибкие элементы массива C-стиля в программе на С++, не полагаясь на расширение для компилятора, вы можете скомпилировать свой C-код как C и связать его с вашей программой на С++. Вы не можете сделать тип с гибким элементом массива, видимым для вашего кода на С++, но вы можете использовать его внутри кода C и, возможно, обеспечить его доступ к вашему коду С++ с помощью непрозрачного указателя. См. Часто задаваемые вопросы по С++ для получения информации о смешении C и С++ в рамках одной и той же программы. (Или вы можете просто использовать расширение g++ за счет того, что вы не можете скомпилировать свой код с другими компиляторами.)

(Я предполагаю, что вы используете g++. Некоторые другие компиляторы, вероятно, реализуют подобные расширения.)

Ответ 2

Нет.

extern "C" является только спецификацией связывания, поэтому к закрытым символам может быть привязан к C. Он не переключает ваш компилятор в режим "C" для раздела кода.

Ответ 3

Объявление extern "C" влияет только на связь внешних функций, так что манипуляция имени не выполняется. Это не означает, что функции будут скомпилированы с использованием правил языка C вместо С++. Другими словами, в том числе код в some_random.cpp не будет определять его поведение.

Ответ 4

Он просто ascii до тех пор, пока компилятор работает. Поэтому препроцессор будет вставлять файлы вместе, тогда компилятор будет обрабатывать результат как любой язык, который вы указали.

Это не член гибкого массива C, это текстовый файл. Undefined остается.