2012-04-03 5 views
1

Я пытаюсь передать некоторый код в GCC, который компилирует ОК с помощью компилятора IAR. Код инициализирует массив объектов C++ (структура с массивом символов). Я могу заставить его работать с GCC на C, но не с C++. Вот простой пример.Инициализация массива _C++ _ объектов с указателями индекса

#include <stdio.h> 

typedef struct 
{ 
int lineID[10]; 
} TMenu; 

static const TMenu t1[8] = 
{ 
    {{3}}, 
    {{4}}, 
    [6] = {{33, 22}}, 
    [8] = {{33, 22}}, 
    {{}}, 
    {{9,8,7,6,5,4,3,2,1}}, 
}; 

ПРИМЕЧАНИЕ: Я также должен был добавить дополнительные фигурные скобки вокруг инициализаторах, что IAR не жаловалась.

Он компилируется с GCC, но при компиляции с G ++ я получаю следующие ошибки.

x.c:12:6: error: expected identifier before numeric constant 
x.c: In lambda function: 
x.c:12:9: error: expected '{' before '=' token 
x.c: At global scope: 
x.c:12:20: error: no match for 'operator=' in '._2 = {{33, 22}}' 
x.c:13:6: error: expected identifier before numeric constant 
x.c: In lambda function: 
x.c:13:9: error: expected '{' before '=' token 
x.c: At global scope: 
x.c:13:20: error: no match for 'operator=' in '._3 = {{33, 22}}' 
+4

Это довольно просто. Это не C++, этот синтаксис не является частью стандарта. –

+0

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

+0

Примечание: использование g ++ 4.5.3 (на OS X). Я использовал g ++ 4.2.1 (стандарт на OS X 10.7), но это дало мне действительно странные ошибки. В настоящее время я устанавливаю g ++ 4.6 и 4.7, чтобы убедиться, что это имеет значение. – BrendanSimon

ответ

0

Я никогда не видел синтаксис как

[6] = {33, 22}}, 

в C++. Вы можете попробовать просто использовать пустые инициализаторы для заполнения пробелов. Следующие работы по ideone:

#include <iostream> 

struct TMenu 
{ 
    int lineID[10]; 
}; 

int main(int, char*[]) 
{ 
    const TMenu t1[8] = 
    { 
    {{3}}, 
    {{4}}, 
    {{33, 22}}, 
    {{33, 22}}, 
    {{}}, 
    {{9, 8, 7, 6, 5, 4, 3, 2, 1}}, 
    }; 
    for (int i = 0; i < 8; ++i) 
    { 
    for (int j = 0; j < 10; ++j) 
    { 
     std::cout << t1[i].lineID[j] << "\t"; 
    } 
    std::cout << std::endl; 
    } 
} 
+0

Да, но в реальном коде указатели являются символьными константами (макросами), используемыми во всем коде. Их около 60. Использование указателей позволяет повысить надежность кода, гарантируя, что константы индекса всегда будут правильными. Странно, что использование C++ даст вам менее надежный код. – BrendanSimon

+0

Пример кода был простым тестовым примером. Реальный код имел бы что-то вроде: [MenuSignOn] = {{1, 2, 3, 4}}, [MenuSetup] = {{28,27,29,30}} и т. Д. Честно говоря, я думаю, что этот модуль должен переписываться, но моя первоначальная цель состояла в том, чтобы просто передать то, что я унаследовал. – BrendanSimon

2

Looks как GCC 4.7 становится все ближе к поддержке этой конструкции. Вот вывод GCC 4.5, 4.6 и 4.7 при компиляции того же примера.

GCC 4.5.3

$ /opt/local/bin/g++-mp-4.5 -Wall -std=c++0x -o y.exe x.c 
x.c:12:6: error: expected identifier before numeric constant 
x.c: In lambda function: 
x.c:12:9: error: expected '{' before '=' token 
x.c: At global scope: 
x.c:12:20: error: no match for 'operator=' in '._2 = {{33, 22}}' 
x.c:13:6: error: expected identifier before numeric constant 
x.c: In lambda function: 
x.c:13:9: error: expected '{' before '=' token 
x.c: At global scope: 
x.c:13:20: error: no match for 'operator=' in '._3 = {{33, 22}}' 

GCC 4.6.3

$ /opt/local/bin/g++-mp-4.6 -Wall -std=c++0x -o y.exe x.c 
x.c:12:6: error: expected identifier before numeric constant 
x.c: In lambda function: 
x.c:12:9: error: expected '{' before '=' token 
x.c: At global scope: 
x.c:12:20: error: no match for 'operator=' in '{} = {{33, 22}}' 
x.c:12:20: note: candidate is: 
x.c:12:7: note: <lambda()>&<lambda()>::operator=(const<lambda()>&) <deleted> 
x.c:12:7: note: no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'const<lambda()>&' 
x.c:13:6: error: expected identifier before numeric constant 
x.c: In lambda function: 
x.c:13:9: error: expected '{' before '=' token 
x.c: At global scope: 
x.c:13:20: error: no match for 'operator=' in '{} = {{33, 22}}' 
x.c:13:20: note: candidate is: 
x.c:13:7: note: <lambda()>&<lambda()>::operator=(const<lambda()>&) <deleted> 
x.c:13:7: note: no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'const<lambda()>&' 

GCC 4.7.0

$ /opt/local/bin/g++-mp-4.7 -Wall -std=c++0x -o y.exe x.c 
x.c:16:1: sorry, unimplemented: non-trivial designated initializers not supported 
x.c:16:1: sorry, unimplemented: non-trivial designated initializers not supported 
+1

Просто попробовал clang-3.0, и ему удалось создать и выполнить правильно :) Итак, похоже, что G ++ немного отстает от времени, даже если он не в спецификации C++, кажется, стоит того, что clang и компиляторы IAR поддерживают это построить. Обратите внимание, что компилятор IAR C++ с 2008 года! – BrendanSimon

+0

Я верю, что clang поддерживает назначенные инициализаторы как расширение, которое должно дать вам предупреждение, если вы скомпилируете '-pendantic'. –

+0

Кажется, не было никаких предупреждающих сообщений, кроме ... clang: warning: аргумент не использовался во время компиляции: '-pendantic' – BrendanSimon

Смежные вопросы