【问题标题】:Strange definition in C with @ signC中带有@符号的奇怪定义
【发布时间】:2015-12-14 16:55:13
【问题描述】:

我在嵌入式 C 源文件中遇到了以下定义:

const preamble_t OAD_Preamble @ ".preamble" =
{
  HAL_OAD_RC_MAX,       // Default program length of max if not using post-processing tool.
  OAD_MANUFACTURER_ID,  // Manufacturer ID
  OAD_TYPE_ID,          // Image Type
  0x00000001            // Image Version
};

我不知道@部分,你能帮我解决这个问题吗?

编辑: 这是在 IAR 编译器中,用于 TI SoC。

【问题讨论】:

  • 建议在您正在使用的编译器中添加标签,因为@ 是非标准扩展。

标签: c embedded iar


【解决方案1】:

这是您可以指定要放置变量的内存地址或部分的方式。

  • ".preamble" 是一个部分的名称,
  • OAD_Preamble 是要放置在那里的变量。

您还可以在@ 符号后指定物理地址:

const unsigned char port_bit @ 0x1800 = BIT0;

更多信息在this document

注意:这是一个不可移植的编译器扩展,不是标准 C 语法的一部分。

【讨论】:

  • 绝对是编译器扩展。我将相同的处理器与(我怀疑)不同的编译器一起使用,并且我们在之前的行中使用了#pragma location = ADDRESS 语法。我碰巧发现它更清晰,虽然不那么紧凑,而且我认为它更有可能是便携的。
  • @ErikJohnson :虽然#pragma 是标准编译器指令,但编译指示本身是编译器特定的。它们仅在编译器无法识别的指令需要被忽略的意义上是可移植的。因此代码将在另一个编译器上编译,但数据可能无法按要求定位。向链接器传达信息的指令始终是特定于工具链的。
  • 非标准@ 符号是嵌入式系统中常见的非标准扩展,其含义始终为“在特定地址分配内存”。有很多嵌入式 C 编译器使用它。然而,语法因编译器而异,因此虽然许多编译器支持某种 @ 符号,但它们的非标准扩展不一定相互兼容。
  • @Clifford 您完全正确,各个编译指示是特定于编译器的,但是我在多个编译器上发现了特定的结构,所以我认为它比@ 结构更容易移植。当然,如果您正在编写真正可移植的代码,那么直接分配到内存位置是一个非常糟糕的主意。另一方面,在为嵌入式裸机(此类结构最常见)编写时,可移植性是次要优先级 - 您正在编写您拥有的硬件,并且不在乎它是否在其他地方运行。
  • @ErikJohnson :请注意,在这种情况下,@ 不是用于定位显式位置,而是用作链接器的指令以在特定链接器部分中定位对象。编译器通常支持名称相似但语法或语义不同的 pragma,编译器甚至不需要为无法识别的 pragma 发出诊断 - 在许多情况下,最好在移植时完全中断代码,以便您知道需要修改的地方。 GCC 的 __attribute__ 语法在大多数情况下更可取(并且在其他几个编译器上也支持)。
猜你喜欢
  • 1970-01-01
  • 2013-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多