您好我有以下测试代码,我对cpp感到困惑。
如果你在library.h中声明一个带有空元素子句的数组..编译器会选择什么?它也没有抱怨,我使用Cygwin。
在library.cpp中,我将值赋给两个元素,编译器是否假设一个元素包含一个元素,我将第二个元素写在数组范围之外?
#ifndef LIBRARY_H
#define LIBRARY_H
class library {
public:
void print();
char a[];
};
#endif
#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]);
}
#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
答案 0 :(得分:10)
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
。