c - 重复的 sprintf 格式模式 - 字符串文字与常量字符字符串和编译器优化



在 C 语言中,编译器通常会优化重复的字符串文字吗?我正在使用 sprintf 语句,这些语句使用 const char 数组为格式重复相同的字符串文字,并注意到映射文件中的内存使用情况没有变化。此测试中使用的编译器是用于嵌入式系统的 IAR。

详细来说,有六个sprintf语句用于创建到不同地址的ping字符串,类似于:

sprintf(pingString, "ping %s 3 1r", "127.0.0.1");
sprintf(pingString, "ping %s 3 1r", primaryDNS);

我用常量字符替换了格式字符串:

const char pingCommandFormat[] = "ping %s 3 1r";
sprintf(pingString, pingCommandFormat, "127.0.0.1");
sprintf(pingString, pingCommandFormat, primaryDNS);

然后编译并检查映射文件,并注意到使用的内存没有变化。

保留字符串文字而不是使用 const char 字符串是可读性的理想选择,但在嵌入式系统中优化内存使用是谨慎的做法。编译器行为永远不应该期望优化,但这种类型的行为在不同的编译器中是否常见?

即使没有启用优化,常数折叠也很常见。

例如,使用以下代码:

#include <stdio.h>
int main()
{
    const char *str1="hello";
    const char *str2="hello";
    printf("%pn", (void *)str1);
    printf("%pn", (void *)str2);
    printf("%pn", (void *)"hello");
    printf("%pn", (void *)"hello");
    return 0;
}

它建立在 CentOS 7.2 和 gcc 4.8.5 作为gcc -g -Wall -Wextra -o x1 x1.c,输出:

0x400630
0x400630
0x400630
0x400630

如您所见,在代码中出现的 4 个位置中的每一个位置"hello"它都引用了相同的字符串文字。

我并不是知道编译器不进行这种优化 - 但如果我没记错的话,这不是标准规定的。

如果是为了可读性:

void createPingString(char const* address)
{
    sprintf(pingString, "ping %s 3 1r", address);
}

也许更好:

void sendPing(char const* address);

还包含所有其他程序...

最新更新