C 编译时浮点打包/双关

C 编译时浮点打包/双关,c,gcc,embedded,type-punning,C,Gcc,Embedded,Type Punning,我正在为PIC32MX编写C,它是用Microchip的PIC32C编译器(基于GCC 3.4)编译的 添加了我遵循的标准是GNU99(带有GNU扩展的C99,编译器标志-std=GNU99) 我的问题是:我有一些可重新编程的数字数据存储在EEPROM或芯片的程序闪存中。这意味着,当我想要存储一个float时,我必须进行一些类型双关: typedef union { int intval; float floatval; } IntFloat; unsigned int flo

我正在为PIC32MX编写C,它是用Microchip的PIC32C编译器(基于GCC 3.4)编译的

添加了我遵循的标准是GNU99(带有GNU扩展的C99,编译器标志
-std=GNU99

我的问题是:我有一些可重新编程的数字数据存储在EEPROM或芯片的程序闪存中。这意味着,当我想要存储一个float时,我必须进行一些类型双关:

typedef union
{
    int intval;
    float floatval;
} IntFloat;

unsigned int float_as_int(float fval)
{
    IntFloat intf;
    intf.floatval = fval;
    return intf.intval;
}

// Stores an int of data in whatever storage we're using
void StoreInt(unsigned int data, unsigned int address);

void StoreFPVal(float data, unsigned int address)
{
    StoreInt(float_as_int(data), address);
}
我还将默认值作为编译时常量数组包含。对于(无符号)整数值,这很简单,我只使用整数文本。但是,对于浮点,我必须使用此Python代码段将它们转换为单词表示形式,以便将它们包含在数组中:

import struct
hex(struct.unpack("I", struct.pack("f", float_value))[0])
…因此,我的默认值数组具有以下无法识别的值:

const unsigned int DEFAULTS[] =
{
    0x00000001, // Some default integer value, 1
    0x3C83126F, // Some default float value, 0.005
}
(这些实际上采取了构造的形式,但在这里没有什么区别。)评论很好,但有更好的方法吗?能够做到以下几点真是太好了:

const unsigned int DEFAULTS[] =
{
    0x00000001, // Some default integer value, 1
    COMPILE_TIME_CONVERT(0.005), // Some default float value, 0.005
}
……但我完全不知所措,我甚至不知道这样的事情是否可能发生

注释

  • 显然,“不,不可能”是一个可以接受的答案,如果是真的
  • 我并不过分担心可移植性,所以实现定义的行为是好的,而未定义的行为则不是(我面前有IDB附录)
  • 据我所知,这需要进行编译时转换,因为
    DEFAULTS
    在全局范围内。如果我错了,请纠正我

  • 您可以将您的
    默认值
    数组改为
    IntFloat
    数组吗

    如果可以,并且编译器支持C99,则可以执行以下操作:

    const IntFloat DEFAULTS[] =
    {
        { .intval = 0x00000001 }, // Some default integer value, 1
        { .floatval = 0.005 }, // Some default float value, 0.005
    };
    

    哎呀,我忘了在Q中提到我遵循的标准。更新后提到:GNU99.caf是正确的,它编译并与GNU99一起工作,我只是尝试了一下。你是说gnu89吗?或者你真的需要一系列整数吗?也不是,我只是还没有机会尝试:)caf的解决方案看起来不错。注意类似于
    #define COMPILE_TIME_CONVERT(x)((IntFloat)(float)(x)).intval
    在gcc的原始默认值[]范围内不起作用。这非常有效,谢谢:)这是C99特性还是GNU扩展?很高兴知道,这样我就可以记录下来了。