C到C ++表内联定义

时间:2018-05-29 11:12:41

标签: c++ c gcc g++

我的C代码编译和正常工作,我想在C ++中使用类似的代码:

static const char* aTable[12] = {
    [4]="seems",
    [6]=" it  ",
[8]="works",};

int main(){
    printf("%s%s%s", aTable[4],aTable[6],aTable[8]); 
    return 0;
}

现在,如果我将其放在.c文件中并使用gcc进行编译,则可以正常工作。但是,如果我将它放在.cpp文件中并使用g++进行编译,我会收到以下错误:

test_cpp.cpp:5:3: error: expected identifier before numeric constant
test_cpp.cpp:5:4: error: type '<lambda>' with no linkage used to declare function 'void<lambda>::operator()() const' with linkage [-fpermissive] 
test_cpp.cpp: In lambda function: test_cpp.cpp:5:5: error: expected '{' before '=' token 
test_cpp.cpp: At global scope: test_cpp.cpp:5:5: warning: lambda expressions only available with
    -std=c++0x or -std=gnu++0x [enabled by default] 
test_cpp.cpp:5:6: error: no match for 'operator=' in '{} = "seems"' test_cpp.cpp:5:6: note: candidate is: test_cpp.cpp:5:4: note: <lambda()>&<lambda()>::operator=(const<lambda()>&) 
test_cpp.cpp:5:4: note:   no known conversion for argument 1 from 'const char [6]' to 'const<lambda()>&' 
test_cpp.cpp:6:3: error: expected identifier before numeric constant
test_cpp.cpp:6:4: error: type '<lambda>' with no linkage used to declare function 'void<lambda>::operator()() const' with linkage [-fpermissive]

有没有办法表达我没有宣布lambda函数,只是试图填表?

我想保留以下部分:

[4]="seems",
[6]=" it  ",
[8]="works",

因为它来自自动生成的文件......

5 个答案:

答案 0 :(得分:28)

您可以轻松地混合使用C和C ++代码。

你应该保持C代码用C编译器(gcc)编译,其余的代码可以是C ++,并用C ++编译器(g ++)编译。然后将所有对象(.o)文件链接在一起。

像这样:

文件名: a.c

const char* aTable[12] = {
    [4]="seems",
    [6]=" it  ",
[8]="works",};

文件名: b.cpp

#include <cstdio>
extern "C" const char* aTable[12];   
int main(){
    printf("%s%s%s", aTable[4],aTable[6],aTable[8]); 
    return 0;
}

现在编译:

gcc -c a.c -o a.o
g++ -c b.cpp -o b.o
g++ b.o a.o -o all.out

现在运行可执行文件(all.out),您将看到一切正常。

请注意,对于函数,您需要在cpp文件中声明之前添加extern "C"

答案 1 :(得分:16)

没有办法做到这一点。 C ++从未采用过这种特殊的C语法。

在您的情况下,由于表是自动生成的,我只需将其放在C文件中。只要它没有标记为static,就可以从C ++代码中访问它而不会出现问题。

答案 2 :(得分:13)

[4]=指定的初始化程序,是C ++不支持的C功能之一。

这是一个list,试图列出C ++ 17支持的C99功能。向下滚动到底部以查看哪些不受支持。

重要的是要认识到C ++绝不是C的超集。

答案 3 :(得分:5)

已经提到的C ++不支持指定的初始化程序 - 如果你坚持使用C ++,你可以编写一个带有构造函数的包装类:

class Table
{
    std::array<char const*, 12> data;
public:
    Table()
    {
        data[4] = "seems";
        data[6] = " it  ";
        data[8] = "works";
    }
    char const* operator[](unsigned int index) const
    {
        return data[index];
    }
} aTable;

没有测试代码,所以如果你发现了一个bug,请随意修复它......

答案 4 :(得分:2)

如上所述,C ++不支持这种类型的初始化,但您可以使用lambda函数初始化static array<const char*, 12>,如下所示:

#include <array>
#include <cstdio>

static const std::array<const char*, 6> aTable = []() {
    std::array<const char*, 6> table;
    table[0] = "Hello";
    table[3] = ", ";
    table[5] = "world!";
    return std::move(table);
}();

int main() {
    printf("%s%s%s\n", aTable[0], aTable[3], aTable[5]);
    return 0;
}

Demo on coliru

值得注意的是,编译器将在此处执行RVO,并且将在适当的位置执行初始化。这是由g ++ - 5.4.0生成的程序集:

<_GLOBAL__sub_I_main>:
movq   $0x40064c,0x200bc5(%rip)        # 601060 <_ZL6aTable>
movq   $0x400652,0x200bd2(%rip)        # 601078 <_ZL6aTable+0x18>
movq   $0x400655,0x200bd7(%rip)        # 601088 <_ZL6aTable+0x28>
retq