【问题标题】:Is it possible to define constants in C at runtime?是否可以在运行时在 C 中定义常量?
【发布时间】:2020-05-13 18:55:27
【问题描述】:

我有一个文件 file1.c,如果满足某些要求,我想在其中定义一些常量,以便在另一个文件 file3.c 中使用。

file1.c:

#include "header.h"

int set_constants(void) {

#ifdef EXAMPLE_MACRO
  int fd, status, size;

  fd = open(EXAMPLE_DRIVER, RD_ONLY);

  ioctl(fd, EXAMPLE_IOCTL_CHECK_SIZE, &size);

  if (size == SIZE_CONDITION) {
    /* Here i would like to define the constants 
       A, B, and C. */
  } else {
    /* Here I would like to define the constants
       A, B, and C to something else than above. */
  }
  return 0;

#endif

/* If EXAMPLE_MACRO is not defined, I would like to set
   A, B and C to something else. */
  return 0;

函数 set_constants() 将从 file2.c 中的 init 函数调用,该函数调用 file3.c 中使用常量 A 的函数:

#include "header.h"

void file2_init(void) {
  set_constants();

  file3_function();
}

在file3.c中,我想用A元素创建一个全局数组:

#include "header.h"

uint8_t array[A];

void file3_function(void) 
{
  /* Do something with array */
}

我知道 A、B 和 C 不能定义为宏,因为在预处理器处理宏时变量 size 是未知的。甚至可以创建这样的常量(使用 C 语言)吗?

我尝试在 file1.c 中将 A、B 和 C 定义为全局整数变量(我知道它们不是常量,但这是我目前唯一的想法),并在头文件中像这样声明它们header.h:

#ifndef _MY_HEADER_H_
#define _MY_HEADER_H

extern int A;
extern int B;
extern int C;

void set_constants(void);
void file3_function(void);

#endif _MY_HEADER_H_

然后我得到错误:

错误:在文件范围内可变地修改了“数组”

array[A] 需要在全局范围内,我的问题是,我如何声明和定义 A、B 和 C 以便它们对 file3.c 可见,而不是升上面的错误?

我也尝试过将 A、B 和 C 设为 const int,就像这样;

#include "header.h" 
int set_constants(void) {

#ifdef EXAMPLE_MACRO
  int fd, status, size;

  fd = open(EXAMPLE_DRIVER, RD_ONLY);

  ioctl(fd, EXAMPLE_IOCTL_CHECK_SIZE, &size);

  if (size == SIZE_CONDITION) {

    const int A = 1;
    const int B = 1;
    const int C = 1;

  } else {

    const int A = 2;
    const int B = 2;
    const int C = 2;
  }
  return 0;

#endif

  const int A = 3;
  const int B = 3;
  const int C = 3;

  return 0;

并在 header.h 中将 A、B 和 C 声明为 extern const int

#ifndef _MY_HEADER_H_
#define _MY_HEADER_H

extern const int A;
extern const int B;
extern const int C;

void set_constants(void);
void file3_function(void);

#endif _MY_HEADER_H_

然后我得到编译错误:

错误:“A”的声明遮蔽了全局声明 [-Werror=shadow] 常量 int A = 1;
在 file1.c 中包含的文件中: header.h:错误:阴影声明在这里 [-Werror=shadow] extern const int A;

【问题讨论】:

  • 您要解决的问题是什么?在编译时定义它们是否会导致任何问题?
  • @pikopiko 正如您可能在其他 cmets 中所读到的,您需要澄清您的问题。重新表述问题中已经存在的信息无济于事。 (就像您刚才在评论中所做的那样)您要解决的原始问题是什么?您需要array[A] 才能在全球范围内吗?你能把它移到file3_function吗?
  • @pikopiko 这不是澄清。它只是重复。我认为你有理由去做你想做的事?
  • @bodo 我需要 array[A] 在全局范围内,我不能将它移动到 file3_function。
  • @pikopiko 请edit您的问题添加说明。解释为什么array[A] 必须是全局的。如果我们知道您最初的问题,我们或许可以提出替代解决方案。

标签: c macros runtime constants extern


【解决方案1】:

要使全局范围的uint8_t array[A]; 工作,A 必须在编译时已知。初始化的内存实际上是在可执行对象文件中找到的。[1] 这样,您将无法使用uint8_t array[A];;您将需要使用动态内存分配(例如malloc)。


  1. 如果它被初始化为全零字节,它被放置在一个在运行时分配的内存页面中,但它全为零的事实仍然必须在编译时知道才能知道采用这种方法。李>

【讨论】:

  • 由于数组没有用值显式初始化,而是用零隐式初始化,因此在可执行对象文件中找不到内存,但保留了bss上的空间。
猜你喜欢
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 2010-10-19
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多