cpp空数组声明

use*_*516 8 c++

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

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

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

library.h

#ifndef LIBRARY_H
#define LIBRARY_H

class library {

public:
    void print();
    char a[];
};

#endif
Run Code Online (Sandbox Code Playgroud)

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]);
}
Run Code Online (Sandbox Code Playgroud)

client.cpp

#include <stdio.h>
#include "library.h"

void execute();
library l;

int main() {
    l = library();
    l.print();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Makefile文件

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
Run Code Online (Sandbox Code Playgroud)

Alo*_*ave 11

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

public:
     void print();
     char a[];
Run Code Online (Sandbox Code Playgroud)

这段代码在C++中完全是非法的.C++中的数组大小需要是正编译时间常量.解决方案是将其替换为:

public:
      void print();
      std::string a;
Run Code Online (Sandbox Code Playgroud)

请注意声明,

char a[];
Run Code Online (Sandbox Code Playgroud)

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

  • 声明`char a []`在C++中也是合法的,也是一个不完整的数组类型.不同的是,在C++中,_all_类成员必须是完整的类型; 在C98(但不是C90)中,有一个特殊的异常允许结构的_last_元素是一个不完整的数组类型(限制你可以用结果结构做什么).而编译器确实没有为它保留任何内存; struct的大小就好像这个元素不在那里(除非它增加了struct的对齐要求). (5认同)

Jam*_*nze 6

首先,它不是合法的C++.这是一个古老的黑客,C只在C98合法化.基本思想是这样struct只能动态分配(使用malloc),然后分配对象后需要很多内存.所以你会做类似的事情malloc( sizeof( library ) + strlen( s ) + 1 ).黑客用于避免额外分配.

使用此hack的类不能使用new,也不能是成员或基类.(它也不能是C中的成员.)

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

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 );
    }
};
Run Code Online (Sandbox Code Playgroud)

但请注意,与C解决方案不同,这会产生对齐问题的风险.它适用于字符类型,如果类的其他成员至少需要与缓冲区类型一样多的对齐,它将起作用,否则它可能会失败.(g ++中std :: basic_string的实现使用它 - 如果实例化的话会在某些机器上崩溃double.)


syl*_*eux 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
Run Code Online (Sandbox Code Playgroud)

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