在 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)
过去 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)