将static const char []设置为预定义的静态const char []失败

时间:2009-11-18 20:45:35

标签: c++

嘿伙计们!当我尝试在头文件中执行以下操作时

static const char FOOT[] = "Foot";
static const char FEET[] = FOOT;

我收到error: initializer fails to determine size of FEET的编译错误。我想知道这是什么原因,以及是否有办法纠正它。谢谢!

6 个答案:

答案 0 :(得分:4)

即使为什么你得到这个错误已被回答,故事还有更多内容。如果你确实需要将FEET作为数组,那么你可以将它作为引用而不是指针:

char const foot[] = "foot";

char const (&feet)[sizeof foot] = foot;
// reference to array (length 5) of constant char
// (read the declarations "from the inside-out")

char const* const smelly_feet = foot;
// constant pointer to const char

int main() {
  cout << sizeof feet << ' ' << feet << '\n';
  cout << sizeof smelly_feet << ' ' << smelly_feet << '\n';
  cout << sizeof(void*) << " - compare to the above size\n";
  return 0;
}

inside-out rule的更多例子。)

其次,文件和命名空间范围内的static表示内部链接;所以当你在标题中使用它时,你会在每个TU中使用该标题获得重复的对象。有些情况下你想要这个,但我认为没有理由在你的代码中,这是一个常见的错误。

关于数组大小: sizeof运算符返回对象或类型实例的内存大小。对于数组,这意味着其所有项目的总内存大小。由于C ++保证sizeof(char)为1,因此char数组的内存大小与其长度相同。对于其他数组类型,可以除以一个项的内存大小以获得数组的长度:

void f() {
  int array[5];
  assert((sizeof array / sizeof *array) == 5);
}

您可以将其概括为功能模板:

template<class T, int N>
int len(T (&)[N]) {
  return N;
}
// use std::size_t instead of int if you prefer

这在boost boost::size中存在。

您可能会看到使用sizeof array / sizeof *array的代码,无论是通过宏还是直接使用,因为它已经过时或者不想使问题复杂化。

答案 1 :(得分:2)

原因是你说FEET []是一个字符数组但是你把它初始化为ptr; 要纠正,您可以将FEET从FEET []更改为* FEET 也可以用FOOT

做同样的事情

答案 2 :(得分:2)

C ++中的数组没有'='运算符,你需要使用strcpy或类似的东西(你不能用静态const做)。根据您的要求,以下内容可能有用:

#define contentsOfFoot "FOOT"
static const char FOOT[5] = contentsOfFoot;
static const char FEET[5] = contentsOfFoot;
static const char *feeet = FOOT;

答案 3 :(得分:2)

不推荐使用

static,无论如何,命名空间范围内的const变量实际上是静态的。另外,请为预处理程序标识符保留ALL_CAPS。

更大的问题是为什么要使用原始数组。你很可能想要更像这样的东西:

std::string const foot = "foot";
std::string const feet = foot;

或者,更有可能:

#include <string>

namespace spbots {

    typedef std::string string_t;

    string_t const foot = "foot";
    string_t const feet = foot;
}

答案 4 :(得分:1)

一种方式是

static const char FOOT[] = "Foot";
static const char *FEET = FOOT;

答案 5 :(得分:1)

我想强调一点,你不应该把这些东西放在头文件中。变量只应放在头文件中,如果你想让它们全局可见(通常不是一个好主意,但它是一种合法的技术)。

feet.h
extern char feet[];

feet.cpp
char feet[] = "FEET";

现在当你在一个不同的 .cpp文件中包含feet.h时,比如leg.cpp,foot.h中的声明意味着leg.cpp可以看到并使用在foot.cpp中定义的数组

extern关键字与您使用的static关键字具有相反的含义。静态的典型用法如下;

feet.cpp
static char feet[] = "FEET";

现在脚[]明显在feet.cpp之外不可见。 static关键字导致缺乏可见性。那么static = local,extern = global和(可能不幸的是?)extern是默认的,所以如果你不使用任何一个关键字,无论你喜欢与否,你都会得到extern。

因为static = local,所以没有什么可以与其他模块通信,所以不需要在头文件中有声明供其他模块查看。一切都保持在foot.cpp之内,可能比全局变量更好。

我隐含地尝试解释这个解释的另一点是声明进入头文件,定义进入.cpp文件。在您的问题中,您在头文件中有一个定义。不是非法的,但是如果你把它包含在多个文件中(如果不包含,为什么要把它放在标题中?),你会得到一个多次定义的变量,这会给你一个链接错误。

在现代意义上,所有这些实际上都是旧学校C而不是C ++。换句话说,你真的在​​编写C语言,但由于C(几乎)是C ++的一个子集,你仍然可以使用C ++来完成这些工作。