0

在一个简单的示例中,我有两个源文件...一个使用特定字符串,如下所示:

main.c

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

int main(int argc, char *argv[])
{
    print_somestring(thestring, (enum strsizes)stringlen);
    return 0;
}

然后这个:

stringdata.c

const unsigned char thestring[] = "This is a string\n";

enum strsizes
{
    stringlen = sizeof(thestring) - 1 //to account for the null byte
};

主要的标题:

stringdata.h

extern const unsigned char thestring[];

extern enum strsizes; //<-- how?

现在,我试图编译它,我得到了我所期望的......它不喜欢它。主要问题是能够让枚举“看到”实际定义的字符串,以便 sizeof 正确评估;单独的 extern 符号不能提供足够的信息,因此我必须在每个编译单元中声明和初始化字符串,这显然会中断。

我知道通常情况下,您会在标头中定义枚举类型,然后在需要它们的地方使用常量。在这种情况下,常量的值取决于编译时条件(评估的字符串“字节”大小)。

为了在其他编译单元中使用这些常量,我需要枚举类型定义来“坚持”,如果你愿意的话。显然,extern 不会这样做。通过使用真实类型(即 const int)使常量占用实际存储空间是我想要避免的。

我已经尝试了很长时间来查找示例,但它们似乎都不是我想要的。我找到的解决方案涉及 C++ 模板元编程,但我严格使用 C。

如果有人可以帮助我,请提前感谢(这将对我的项目产生其他非常有益的影响)。

4

1 回答 1

2

你实际上可以做到这一点。

首先,将执行此操作所需的所有字符串定义为头文件中的宏,例如:

#define THE_STRING "This is a string\n"

然后在头文件中为您的枚举创建一个 typedef,或者包含它:

typedef enum {
    stringlen = sizeof(THE_STRING) -1 
} the_enum_t;

现在在一些 C 源文件中分配一个枚举实例

#include "headerfile.h"

the_enum_t strsizes = stringlen;

最后在其他文件中,使用它:

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

extern the_enum_t strsizes;

int main (int argc, char ** argv) {
  printf("length is %d\n", strsizes);
  return 0;
}

编译并链接并运行它。您将看到您能够访问枚举的值。如果您 objdump 二进制文件,您将看到为 enum 变量分配的空间。但是您不会看到字符串本身出现在二进制文件的任何地方,因为它的长度已经在编译时进行了评估,并且字符串的实际内容(到目前为止)在程序中的任何地方都没有使用。

关键点是

1) 如果要在文件之间共享自定义数据类型,请创建 typedef,然后共享它的实例。

2)如果您不打算使用字符串的内容,请不要定义字符串变量,而只需在编译时使用字符串常量来评估它的长度。如果您打算同时使用这两种方法,请将字符串常量定义为宏,从而实现这两种目的。

于 2013-09-12T02:19:38.940 回答