在 C 中与 flex 相乘时间接需要指针

Indirection requires pointer when multiplying with flex in C

过去 3 小时我一直在尝试解决这个问题,在解决其他问题后,我又遇到了另一个问题。

假设我有一个名为 "main.c":

的 flex 文件
%{
#include <stdio.h>
#include <stdint.h>
uint32_t WAV_BPM = 120;
uint64_t WAV_ALLOC = 0;
uint32_t WAV_SAMPLE_RATE = 44100;
#define WAV_BPM_PERIOD (double) 60*WAV_SAMPLE_RATE/WAV_BPM;
%}

%%
"NOTE_1" {WAV_ALLOC += WAV_BPM_PERIOD*4;}
"NOTE_2" {WAV_ALLOC += WAV_BPM_PERIOD*2;}
"NOTE_4" {WAV_ALLOC += WAV_BPM_PERIOD;}
"NOTE_8" {WAV_ALLOC += (uint64_t) WAV_BPM_PERIOD/2.0;}
.        {printf("unknown character %s\n", yytext);}
%%

int main(int argc, char *argv[]){
  return 0;
}

在我尝试使用 flex -o mainlex.c main.c && gcc -lfl mainlex.c 执行此操作后,我收到 gcc 的错误消息:

main.c:11:29: error: indirection requires pointer operand ('int' invalid)
{WAV_ALLOC += WAV_BPM_PERIOD*4;}
                            ^~
...

这是怎么发生的?我不是在处理指针,我只是在乘以变量。当我将 #define WAV_BPM_PERIOD (double) 60*WAV_SAMPLE_RATE/WAV_BPM; 替换为 double WAV_BPM_PERIOD = (double) 60*WAV_SAMPLE_RATE/WAV_BPM; 时,gcc 给了我另一个问题:

main.c:7:52: error: initializer element is not a compile-time constant
double WAV_BPM_PERIOD = (double) 60*WAV_SAMPLE_RATE/WAV_BPM;
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~

How did this happen?

草率的宏。您有一个杂散的分号,因此编译器会看到 (double) 60*WAV_SAMPLE_RATE/WAV_BPM;*4。一个合适的宏应该写成:

#define WAV_BPM_PERIOD (60.0*WAV_SAMPLE_RATE/WAV_BPM)

error: initializer element is not a compile-time constant

它说的是,初始化器不是编译时常量。这是常见问题解答,您不能用其他变量初始化文件范围变量 ("globals"),因为变量既不是在编译时解析的,也不是整数常量表达式。您可以通过将 WAV_SAMPLE_RATE 等的声明更改为 #define WAV_SAMPLE_RATE 44100 而不是变量来解决此问题。

因为你的#define 后面有分号:

#define WAV_BPM_PERIOD (double) 60*WAV_SAMPLE_RATE/WAV_BPM;

当编译器将它插入到代码中时,它看起来像:

#define WAV_BPM_PERIOD (double) 60*WAV_SAMPLE_RATE/WAV_BPM;*4;

宏是编译前复制并粘贴到您的代码中的文本,因此始终应如此对待。

您应该只删除分号或将您的定义放在括号中然后删除分号,具体取决于您要执行的操作。

#define WAV_BPM_PERIOD (double) 60*WAV_SAMPLE_RATE/WAV_BPM

#define WAV_BPM_PERIOD (double) (60*WAV_SAMPLE_RATE/WAV_BPM)