c - "Section type conflict"由于 GCC 4.8.2 中的宏定义

标签 c arduino

如果我在内联函数中调用宏,则会出现“节类型冲突”。 在 WWW 中找不到任何有关此错误的信息。

该宏的目的是提供一个宏来处理保存在 Arduino 闪存中的字符串(只是一个侧面信息)。 如果函数没有内联,一切都很好。可能是什么原因?

#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))

#undef PSTR
/* need to define prog_char in avr-gcc 4.7 */
#if __AVR__ && __GNUC__ == 4 && __GNUC_MINOR__ > 6
typedef char prog_char;
#endif
/* Need const type for progmem - new for avr-gcc 4.6 */
#if __AVR__ && __GNUC__ == 4 && __GNUC_MINOR__ > 5
#define PSTR(s) (__extension__({static const prog_char __c[] PROGMEM = (s); \
                                  (const prog_char_t *)&__c[0]; }))
#else
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); \
                                  (prog_char_t *)&__c[0]; }))
#endif

代码:

inline void test() {
    hal.console->println("AP_Common tests\n");
    hal.console->println_P(PSTR("AP_Common tests\n") );
    hal.console->printf_P(PSTR("AP_Common tests\n") );
}

void setup(void)
{
  test();
}

void loop(void)
{
    // do nothing
}

错误:“println_P(PSTR(“错误的变量表\n”));”

AP_HAL/utility/BetterStream.h:53:57: note: in definition of macro 'printf_P'
 #define printf_P(fmt, ...) _printf_P((const prog_char *)fmt, ## __VA_ARGS__)
                                                         ^
output_debug.h:13:26: note: in expansion of macro 'PSTR'
   hal.console->printf_P( PSTR("{\"t\":\"s_cmp\",\"h\":%.1f}\n"),
                          ^
AP_Progmem/AP_Progmem_AVR.h:25:56: note: '__c' was declared here
 #define PSTR(s) (__extension__({static const prog_char __c[] PROGMEM = (s); \
                                                        ^
AP_HAL/utility/BetterStream.h:53:57: note: in definition of macro 'printf_P'
 #define printf_P(fmt, ...) _printf_P((const prog_char *)fmt, ## __VA_ARGS__)
                                                         ^
AP_test.ino:60:27: note: in expansion of macro 'PSTR'

编辑:

在派生类中调用 PSTR() 两次会导致相同的问题。 我认为这是一个编译器错误,导致未定义的行为。

最佳答案

尝试:PROGMEM static const prog_char __c[]。奇怪的是,我发现该属性必须位于声明之前不确定您的版本实际上是做什么的。这很可能就是问题所在。

或者:节类型是存储值的本地内存节的属性。我想这是由链接器报告的。 PROGMEM 部分默认为 NOLOAD(这对于本部分来说是有意义的)。但是,由于初始化,编译器要求该部分相反,从而导致错误。即使这不是真的,我也会在这方面寻找问题。

一些补充说明:

  • 使用 stdint 类型,不要依赖内置类型的大小。
  • 小心“char”。仅用于实际字符,不要依赖其符号性。如果您必须关心不同的类型(uint8_t 或 int8_t)会更合适。
  • `#undef'宏不在使用之前,但在必要时之后。否则,意外的重新定义可能会在没有警告的情况下通过。这些错误可能很难调试!在 header 中使用防护措施。
  • 在微 Controller 中,常量正确性至关重要,因此请明智地使用它。不要不要避免const,即使这需要更多的努力(直到您获得更多经验)。这不仅可以在编译时检测常见缺陷,还可以节省 RAM 和(甚至可能)闪存,因为非常量变量存储在 RAM 中,初始化值则存储在 Flash 中。
  • 请勿在自定义代码中使用 __ 前缀。这些应该保留给工具链的编译器和系统库)。不过,您可以使用它作为后缀(但为什么在示例中??)
  • 避免类型转换。初学者代码中的大多数强制转换实际上是不必要的,或者是糟糕的界面设计的症状。基本上:如果您不必指定函数参数的类型,则不需要类型转换。 (是的,也有异常(exception) - 这就是为什么我称其为基本规则,而不是法律)。
  • 一般来说:使用您能从编译器获得的所有帮助。嵌入式调试并不是很有趣。

关于c - "Section type conflict"由于 GCC 4.8.2 中的宏定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30032468/

相关文章:

c++ - 根据数组检查值时 Arduino 出错

c++ - 将状态枚举的全局更改为函数中的 int 值

c - 如何处理 strerror_r 函数返回的指针?

c++ - 如何使用 Arduino 开始编程/与成品硬件通信?

c - 从文件中获取不带标点符号的字符串以进行拼写检查并输出原始标点符号。

c++ - 错误 C2143 : syntax error : missing '{' before '*'

crash - 12小时后Arduino 'crashed?'

c++ - Arduino:显示的自定义类不起作用;没有编译器错误

c - x86, amd64 : Why SIGTRAP' ucontext instruction pointer does not point to related int3

c - opencl在内核中迭代数组