围绕初始化元素的好方法不是 C 中的常量错误?
Good way around initializer element is not constant error in C?
使用 avr-gcc 时出现 initializer element is not constant
编译错误。有什么好的方法可以做我在这里想做的事情吗?
file.c
#include "file.h"
#include "../notes/octave_two_notes.h"
//F2 is defined in octave_two_notes.h
//This is the file giving me the compilation error
struct Song_Note F2_500ms = { .note = F2, .duration_ms = 500 };
song_note.h
#include "note.h"
struct Song_Note {
struct Note note;
uint16_t duration_ms;
} Song_Note;
octave_two_notes.h
extern struct Note F2;
octave_two_notes.c
#define CALC_CTC_FREQ(clock_freq, prescaler, note_freq_hz) ( (uint32_t) clock_freq / ( (uint16_t) note_freq_hz * (uint16_t) prescaler * 2) - 1)
struct Note F2 = {.freq_hz = 87, .ocr_val = CALC_CTC_FREQ(16000000, 8, 87)};
note.h
#include <stdint.h>
struct Note {
uint16_t freq_hz;
uint16_t ocr_val;
} Note;
首先,这些变量都应该声明为const
。主要是因为你希望它们在闪存中,而不是在 RAM 中。
不幸的是,const
不会解决主要问题,因为 C 语言甚至不将 const
限定的变量视为常量表达式。在文件范围内声明的变量具有 "static storage duration",因此必须使用常量表达式进行初始化。
C 提供的唯一解决方案几乎就是将初始化列表声明为不优雅的宏,在这种情况下,它必须位于头文件中:
// header file
#define CALC_CTC_FREQ ...
#define F2_INIT \
{ \
.freq_hz = 87, \
.ocr_val = CALC_CTC_FREQ(16000000, 8, 87) \
}
并在 .c 文件中使用该宏:
// c file
const struct Note F2 = F2_INIT;
然后在其他地方的 .c 文件中:
const struct Song_Note F2_500ms = { .note = F2_INIT, .duration_ms = 500 };
请注意 CALC_CTC_FREQ
部分应该没问题,其中的所有内容都是常量表达式,并在编译时计算。
使用 avr-gcc 时出现 initializer element is not constant
编译错误。有什么好的方法可以做我在这里想做的事情吗?
file.c
#include "file.h"
#include "../notes/octave_two_notes.h"
//F2 is defined in octave_two_notes.h
//This is the file giving me the compilation error
struct Song_Note F2_500ms = { .note = F2, .duration_ms = 500 };
song_note.h
#include "note.h"
struct Song_Note {
struct Note note;
uint16_t duration_ms;
} Song_Note;
octave_two_notes.h
extern struct Note F2;
octave_two_notes.c
#define CALC_CTC_FREQ(clock_freq, prescaler, note_freq_hz) ( (uint32_t) clock_freq / ( (uint16_t) note_freq_hz * (uint16_t) prescaler * 2) - 1)
struct Note F2 = {.freq_hz = 87, .ocr_val = CALC_CTC_FREQ(16000000, 8, 87)};
note.h
#include <stdint.h>
struct Note {
uint16_t freq_hz;
uint16_t ocr_val;
} Note;
首先,这些变量都应该声明为const
。主要是因为你希望它们在闪存中,而不是在 RAM 中。
const
不会解决主要问题,因为 C 语言甚至不将 const
限定的变量视为常量表达式。在文件范围内声明的变量具有 "static storage duration",因此必须使用常量表达式进行初始化。
C 提供的唯一解决方案几乎就是将初始化列表声明为不优雅的宏,在这种情况下,它必须位于头文件中:
// header file
#define CALC_CTC_FREQ ...
#define F2_INIT \
{ \
.freq_hz = 87, \
.ocr_val = CALC_CTC_FREQ(16000000, 8, 87) \
}
并在 .c 文件中使用该宏:
// c file
const struct Note F2 = F2_INIT;
然后在其他地方的 .c 文件中:
const struct Song_Note F2_500ms = { .note = F2_INIT, .duration_ms = 500 };
请注意 CALC_CTC_FREQ
部分应该没问题,其中的所有内容都是常量表达式,并在编译时计算。