[英]cpp empty array declaration
您好我有以下測試代碼,我對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
public:
void print();
char a[];
這段代碼在C ++中完全是非法的。 C ++中的數組大小需要是正編譯時間常量。 解決方案是將其替換為:
public:
void print();
std::string a;
請注意聲明,
char a[];
在C99和有效它被稱為不完全數組類型 ,C標准保證a
可存儲的類型的ATLEAST一個元件char
。 這在C ++中無效。 C ++標准不允許這些。 僅僅因為兩者都是不同的語言。
首先,它不是合法的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 );
}
};
但請注意,與C解決方案不同,這會產生對齊問題的風險。 它適用於字符類型,如果類的其他成員至少需要與緩沖區類型一樣多的對齊,它將起作用,否則它可能會失敗。 (g ++中std :: basic_string的實現使用它 - 如果用double
實例化,它將在某些機器上崩潰。)
空數組聲明一個零長度數組。 它通過將結構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。
它通常被稱為C中的struct hack 。它使用一個名為flexible array member的特性。
但這不是任何C ++標准規范的一部分。 看看這個問題 。
請注意,觀察某些東西顯然有效並不意味着您可以依賴它來可靠地工作。 如果行為未定義,從技術上講任何事情都可能發生。 包括猛禽突然襲擊。
在C ++中,您可能會使用std::vector<char>
或std::string
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.