为什么这些方法会使我的程序变得更大?

时间:2013-11-25 22:08:17

标签: c++ c function arduino

我正在处理一些Arduino代码并拥有以下代码:

uint8_t world[24][2][3];
bool getDispPixel(uint8_t x, uint8_t y, uint8_t num)
{
    static uint8_t rowByte = 0; // 0 means top 8, 1 means bottom 8
    static uint8_t rowBit = 0;

    if(y > 7)
    {
        rowByte = 1;
        rowBit = x - 8;
    }
    else
    {
        rowByte = 0;
        rowBit = x;
    }

    return (world[x][rowByte][num] & (1 << rowBit)) > 0;
}

void setDispPixel(uint8_t x, uint8_t y, uint8_t num, bool state)
{
    static uint8_t rowByte = 0; // 0 means top 8, 1 means bottom 8
    static uint8_t rowBit = 0;

    if(y > 7)
    {
        rowByte = 1;
        rowBit = x - 8;
    }
    else
    {
        rowByte = 0;
        rowBit = x;
    }

    if(state)
        world[x][rowByte][num] |= (1 << rowBit);
    else
        world[x][rowByte][num] &= ~(1 << rowBit);
}

这些方法的奇怪之处在于为程序添加了大小的TON。甚至只是它的一部分。如果我只从其中一个方法中注释掉以下部分,它会从程序大小中删除2536个字节!

if(y > 7)
{
    rowByte = 1;
    rowBit = x - 8;
}
else
{
    rowByte = 0;
    rowBit = x;
}

两种方法都经常被调用,超过200次组合。如果它们被标记为内联,我会相信它,但它们不是。有什么可能导致这种情况的想法吗?

更新:如果我完全注释掉这些方法&#39;内容它的大小减少了20k!看起来每个函数调用都会占用94个字节。不知道为什么......

2 个答案:

答案 0 :(得分:5)

如果Arduino工具链支持GCC扩展(并且一些快速搜索建议它),那么您可以使用__attribute__((noinline))禁用这些函数的内联,如下所示:

bool getDispPixel(uint8_t x, uint8_t y, uint8_t num) __attribute__((noinline));
bool getDispPixel(uint8_t x, uint8_t y, uint8_t num)
{
    // body of the function here
}

void setDispPixel(uint8_t x, uint8_t y, uint8_t num, bool state) __attribute((noinline));
void setDispPixel(uint8_t x, uint8_t y, uint8_t num, bool state)
{
    // body of the function here
}

额外的线看起来多余,但不是。这就是扩展语法的工作原理。

答案 1 :(得分:2)

以下是输出: nm --print-size --size-sort --radix=d --demangle GOLClock.cpp.o (按大小排列对象的大小):

http://pastebin.com/rHEhuEKg

您可以看到函数SetDispPixel的汇编代码占用148个字节,函数GetDispPixel占用94个字节。

如果它导致二进制文件大量增加,则可能意味着您的函数被内联。