c - 强制编译器在预处理期间进行算术计算

标签 c compiler-errors c-preprocessor pic mplab

编译器:MPLABX IDE V5.30 操作系统:Windows 10

我正在尝试做的是定义一些常量值(以使将来的更改更容易)并在预处理期间通过算术运算创建一些其他常量。然后在运行时使用这些常量。

这是我的意图的示例版本;

#include <stdio.h>
#include <math.h>

#define foo 100 //in case you change FOO in circuit, change this too!
#define bar (sqrt(foo))

int main(void) {
    if ( bar > user_input)
    {
    do();
    }
}

问题是,我想,因为输入是一个常量值,定义的东西会被编译器计算,bar会被10取代 而不是 (sqrt(foo))。但是当我编译它时,数据和程序大小发生了巨大变化。当我拆解它时,有大量的说明,而不是简单地直接在其中输入数字。

然后我按照另一个问题的答案提出的建议放置了一个 const squareroot() 函数和 const int 声明,但编译器给出了类似这样的警告; main.c:50:38: 错误:初始化元素不是编译时常量

here is the second try;
#include <stdio.h>
#include <squareroot.h>

#define foo 100 //in case you change FOO in circuit, change this too!
const int bar=squareroot(foo);

int main(void) {
    if ( bar > user_input)
    {
    do();
    }
}

const int squareroot(const int input)
{
do()
}

我如何向我的编译器表达自己的意思,让它理解我的代码中的某些行在运行时无论发生什么都是不变的,这样它就可以进行算术而不是简单地将标记/文本传递给函数体?

最佳答案

#define 是纯文本替换,仅此而已。所有 #define 转换都发生在预处理翻译阶段,该阶段在任何表达式分析等之前。

编译器必须在常量表达式中支持哪些表达式的列表可以在当前 C 标准的第 6.6 节中找到,以获取摘要 see here .不包括调用函数。

(当然,个别编译器可能会提供标准不需要的功能)。

如果您必须使用不支持在常量表达式中调用浮点函数 sqrt 的编译器,那么您的选择包括:

  • 硬编码您的常量,运行另一个预处理阶段以根据需要设置它们。
  • 有一个在 main 函数开始时初始化的全局变量。

关于c - 强制编译器在预处理期间进行算术计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62524398/

相关文章:

c - 读取一个 32 位整数的第 31 位的值

css - Sass 中的三 Angular 函数——预处理器错误

android - 无法使用android SDK编译项目

c++ - 宏作为预处理器指令的参数

swift - SwiftUI 中的预览真的需要#if DEBUG 语句才能在发布版本中将其删除吗?

c - 将每个由一个或多个空格和/或制表符组成的字符串替换为一个空格

c - 如何声明在另一个结构内声明的结构变量?

c++ - 是否可以从 clang 的解析树中提取预处理器信息?

c - 在 Debian 上构建 DBD Sybase 的问题

java - 为什么不能在If语句中检查方法是否返回true?