Косвенное обращение требует указателя при умножении на гибкость в C - PullRequest
0 голосов
/ 18 июня 2020

Я пытался решить эту проблему последние 3 часа, и после решения других проблем у меня возникли другие проблемы.

Предположим, у меня есть гибкий файл с именем «main. c»:

%{
#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, я получил сообщение об ошибке от g cc:

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;, g cc дает мне другую проблему:

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

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Как это произошло?

Неряшливые макросы. У вас стоит паразитная точка с запятой, поэтому компилятор видит (double) 60*WAV_SAMPLE_RATE/WAV_BPM;*4. Правильный макрос был бы записан как:

#define WAV_BPM_PERIOD (60.0*WAV_SAMPLE_RATE/WAV_BPM)

ошибка: элемент инициализатора не является константой времени компиляции

То, что он говорит, инициализатор не является константой времени компиляции. Это FAQ, вы не можете инициализировать переменные области файла ("глобальные переменные") с другими переменными, так как переменная не разрешается ни во время компиляции, ни в целочисленном константном выражении. Вы можете решить эту проблему, изменив объявление WAV_SAMPLE_RATE et c на #define WAV_SAMPLE_RATE 44100 вместо переменной.

0 голосов
/ 18 июня 2020

это из-за точки с запятой после вашего #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)
...