简体   繁体   English

cpp空数组声明

[英]cpp empty array declaration

Hello I have the following test code and I am confused about cpp. 您好我有以下测试代码,我对cpp感到困惑。

  1. If you declare in library.h an array with an empty element clause .. what will the compiler pick? 如果你在library.h中声明一个带有空元素子句的数组..编译器会选择什么? It does also not complain, I use Cygwin. 它也没有抱怨,我使用Cygwin。

  2. In library.cpp I assign values to two elements, is the compiler assuming an array with one element and I write the second element outside the scope of the array? 在library.cpp中我为两个元素赋值,是编译器假设一个元素有一个元素,我写第二个元素在数组范围之外?

library.h library.h

#ifndef LIBRARY_H
#define LIBRARY_H

class library {

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

#endif

library.cpp 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 client.cpp

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

void execute();
library l;

int main() {
    l = library();
    l.print();
    return 0;
}

Makefile 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
  1. There is no language called C/C++, So your Q cannot be tagged with both. 没有一种叫做C / C ++的语言,所以你的Q不能用两者来标记。
  2. Since you are using classes, Your program can only be C++ and not C. 由于您正在使用类,您的程序只能是C ++而不是C.

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

This code is simply illegal in C++. 这段代码在C ++中完全是非法的。 Array size in C++ needs to be positive compile time constant. C ++中的数组大小需要是正编译时间常量。 Solution is to replace it by: 解决方案是将其替换为:

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

Note that the declaration, 请注意声明,

char a[];

is valid in c99 and it is known as Incomplete array type , the C standard guarantees that a can store atleast one element of the type char . 在C99和有效它被称为不完全数组类型 ,C标准保证a可存储的类型的ATLEAST一个元件char This is not valid in C++. 这在C ++中无效。 C++ standard does not allow these. C ++标准不允许这些。 Simply because both are different languages. 仅仅因为两者都是不同的语言。

First, it's not legal C++. 首先,它不是合法的C ++。 It's an old hack, which C only made legal in C98. 这是一个古老的黑客,C只在C98合法化。 The basic idea is that such struct can only be dynamically allocated (using malloc ), and you allocate however much memory is needed for the object after it. 基本思想是这样的struct只能动态分配(使用malloc ),然后分配后面的对象需要很多内存。 So you'll do something like malloc( sizeof( library ) + strlen( s ) + 1 ) . 所以你会做类似malloc( sizeof( library ) + strlen( s ) + 1 )事情。 The hack is used to avoid an extra allocation. 黑客用于避免额外分配。

A class which uses this hack cannot be used with new , nor can it be a member or a base class. 使用此hack的类不能new一起使用,也不能是成员或基类。 (It cannot be a member in C, either.) (它也不能是C中的成员。)

You can sort of emulate this in 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 );
    }
};

Note, however, that unlike the C solution, this runs the risk of alignment problems. 但请注意,与C解决方案不同,这会产生对齐问题的风险。 It works fine for character types, and it will work if other members of the class require at least as much alignment as the buffer type, but it can fail otherwise. 它适用于字符类型,如果类的其他成员至少需要与缓冲区类型一样多的对齐,它将起作用,否则它可能会失败。 (The implementation of std::basic_string in g++ uses it—and will crash on some machines if instantiated with double .) (g ++中std :: basic_string的实现使用它 - 如果用double实例化,它将在某些机器上崩溃。)

The empty array declares a zero-length array. 空数组声明一个零长度数组。 It is used in C by placing a structure S in a memory zone bigger than sizeof(S) and then using the array to access the remaining memory: 它通过将结构S放在大于sizeof(S)的内存区域中,然后使用该数组访问剩余内存来在C中使用:

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

This is a trick that is a lot less useful in C++. 这是一个在C ++中没那么有用的技巧。 Simply use std::vector instead. 只需使用std :: vector。

It's commonly referred to as the struct hack in C. It uses a feature called flexible array member . 它通常被称为C中的struct hack 。它使用一个名为flexible array member的特性。

This is however not part of any C++ standard specification. 但这不是任何C ++标准规范的一部分。 Have a look at this question . 看看这个问题

Note that the observation that something apparantly does work does not imply that you can rely on it to work reliably. 请注意,观察某些东西显然有效并不意味着您可以依赖它来可靠地工作。 If the behavior is undefined, technically anything can happen. 如果行为未定义,从技术上讲任何事情都可能发生。 Including raptors suddenly attacking. 包括猛禽突然袭击。

In C++ you probably would use a std::vector<char> or a std::string instead. 在C ++中,您可能会使用std::vector<char>std::string

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM