cpp空数组声明

时间:2013-03-19 08:27:15

标签: c++

您好我有以下测试代码,我对cpp感到困惑。

  1. 如果你在library.h中声明一个带有空元素子句的数组..编译器会选择什么?它也没有抱怨,我使用Cygwin。

  2. 在library.cpp中,我将值赋给两个元素,编译器是否假设一个元素包含一个元素,我将第二个元素写在数组范围之外?

  3. library.h

    #ifndef LIBRARY_H
    #define LIBRARY_H
    
    class library {
    
    public:
        void print();
        char a[];
    };
    
    #endif
    

    library.cpp

    #include <stdio.h>
    #include "library.h"
    
    void library::print() {
        a[0] = 'a';
        printf("1. element: %d\n", a[0]);
        a[1] = 'b';
        printf("2. element: %d\n", a[1]);
    }
    

    client.cpp

    #include <stdio.h>
    #include "library.h"
    
    void execute();
    library l;
    
    int main() {
        l = library();
        l.print();
        return 0;
    }
    

    生成文件

    OPTIONS=-Wall
    
    all: main
    
    run: main
            ./main.exe
    
    main: client.o library.o
            g++ $(OPTIONS) -o main $^
    
    library.o: library.cpp library.h
            g++ $(OPTIONS) -c $<
    
    .cpp.o:
            g++ $(OPTIONS) -c $<
    
    clean:
            rm -r *.o
    

4 个答案:

答案 0 :(得分:10)

  1. 没有一种叫做C / C ++的语言,所以你的Q不能用两者标记。
  2. 由于您正在使用类,因此您的程序只能是C ++而不是C.

  3. public:
         void print();
         char a[];
    

    这段代码在C ++中是非法的。 C ++中的数组大小需要是正编译时间常量。解决方案是通过以下方式替换它:

    public:
          void print();
          std::string a;
    

    请注意声明,

    char a[];
    

    在c99中有效且称为不完整数组类型,C标准保证a可以存储至少一个char类型的元素。这在C ++中无效。 C ++标准不允许这些。仅仅因为两者都是不同的语言。

答案 1 :(得分:6)

首先,它不是合法的C ++。这是一个旧的黑客,C只做了 在C98合法。基本的想法是这样的struct只能是。malloc 动态分配(使用malloc( sizeof( library ) + strlen( s ) + 1 ))然后分配 后面的对象需要很多内存。所以你会这样做 像new这样的东西。 黑客用于避免额外的分配。

使用此hack 的类不能class Library { // ... char* buffer() { return reinterpret_cast<char*>( this + 1 ); void* operator new( size_t n, size_t extra ) { assert( n == sizeof( Library ) ); return ::operator new( n + extra ); } }; 一起使用,也不能 它可以是成员还是基类。 (它不能成为一个成员 C,要么。)

你可以用C ++来模拟它:

double

但请注意,与C解决方案不同,这会带来风险 对齐问题。它适用于字符类型,它 如果班上的其他成员至少需要那么多,那就行了 alignment作为缓冲区类型,但否则会失败。 (该 在g ++中实现std :: basic_string使用它 - 和 如果使用{{1}}实例化,将在某些计算机上崩溃。)

答案 2 :(得分:5)

空数组声明一个零长度数组。它通过将结构S放在大于sizeof(S)的内存区域中,然后使用该数组访问剩余内存来在C中使用:

memory* ptr = malloc(sizeof(memory) + sizeof(char) * 10);
// you can now manipulate ptr->a as an array of 10 elements

这是一个在C ++中没那么有用的技巧。只需使用std :: vector。

答案 3 :(得分:1)

它通常被称为C中的struct hack。它使用名为灵活数组成员的功能。

然而,这不是任何C ++标准规范的一部分。看看this question

请注意,观察某些内容确实有效并不意味着您可以依赖它来可靠地工作。如果行为未定义,从技术上讲任何事情都可能发生。包括突然袭击的猛禽。

在C ++中,您可能会改为使用std::vector<char>std::string