【问题标题】:"sprintf" error in esp-idf. gcc version 9.1.0 in msys2esp-idf 中的“sprintf”错误。 msys2 中的 gcc 版本 9.1.0
【发布时间】:2020-07-04 08:41:32
【问题描述】:

我之前在 gcc 6.4.0 中使用 msys2,并且正在为我的项目工作。我将工具链和 gcc 升级到 9.1.0。现在我收到此错误:

一小部分代码:

    memset(payload, 0, 8192);
    sprintf(payload, "GET %s%s HTTP/1.1\r\n", dynamic_fota_url, 
    new_firmware_version);
    sprintf(payload, "%sHost: %s\r\n", payload, dynamic_hostname);
    sprintf(payload, "%sPort: 443\r\n", payload);
    sprintf(payload, "%sAccept: */*\r\n\r\n", payload);

错误信息是:-

D:/dozee/dozee_compiler/msys32/home/esp-idf/examples/dozee_fw_v62/main/dozee_next.c:2092:12: error: passing argument 1 to restrict-qualified parameter aliases with argument 3 [-Werror=restrict]
    sprintf(payload, "%sPort: 443\r\n", payload);
            ^~~~~~~                     ~~~~~~~
D:/dozee/dozee_compiler/msys32/home/esp-idf/examples/dozee_fw_v62/main/dozee_next.c:2093:12: error: passing argument 1 to restrict-qualified parameter aliases with argument 3 [-Werror=restrict]
    sprintf(payload, "%sAccept: */*\r\n\r\n", payload);
            ^~~~~~~                           ~~~~~~~
D:/dozee/dozee_compiler/msys32/home/esp-idf/examples/dozee_fw_v62/main/dozee_next.c:2344:15: error: passing argument 1 to restrict-qualified parameter aliases with argument 3 [-Werror=restrict]
       sprintf(payload, "%sHost: %s\r\n", payload, dynamic_hostname);
               ^~~~~~~                    ~~~~~~~
D:/dozee/dozee_compiler/msys32/home/esp-idf/examples/dozee_fw_v62/main/dozee_next.c:2345:15: error: passing argument 1 to restrict-qualified parameter aliases with argument 3 [-Werror=restrict]
       sprintf(payload, "%sPort: 443\r\n", payload);

我该如何解决这个问题。如何将我的 gcc 降级到以前的版本?

【问题讨论】:

    标签: c gcc embedded msys2 esp-idf


    【解决方案1】:

    错误:将参数 1 传递给具有参数 3 的限制限定参数别名

    如何解决这个问题。

    不要将参数 1 与任何其他参数作为 printf 的别名。

    sprintf(some_buffer, "%s fmt string", some_different_buffer);
    

    为缓冲区设置别名无效且不允许这样做,并导致undefined behavior。您写入和读取的缓冲区不允许重叠。

    使用strcat 附加到字符串。或者通过移动与sprintf 一起使用的缓冲区起始位置来计算偏移量并附加到缓冲区。更喜欢使用snprintf 而不是sprintfsnprintfsprintf 返回写入的字节数(不包括零终止字节),使用该计数。使用snprintf 附加到缓冲区的典型用法可能如下所示:

    char payload[200];
    int len = snprintf(payload, sizeof(payload), "initialize");
    len += snprintf(payload + len, sizeof(payload) - len, "Port: 443\r\n", payload);
    len += snprintf(payload + len, sizeof(payload) - len, "Accept: */*\r\n\r\n", payload);
    

    【讨论】:

    • 这是在 sprintf 的最新 gcc 编译器中添加的,因为当我使用旧 gcc 进行编译时,它工作正常。顺便说一句,感谢您的建议,并将尝试此实现。
    • @MurlidharRoy 这永远是未定义的行为;只是 gcc 在最近的版本中才开始警告它。
    • @MurlidharRoy it was working fine 是未定义行为的完美示例。
    • 为什么会出现这个错误 - error: '%d' directive writing between 1 and 3 bytes into a region of size 2 [-Werror=format-overflow=] sprintf(gain_str, "%d", live_gain-30); 3824:20: note: directive argument in the range [-30, 225] sprintf(gain_str, "%d", live_gain-30); ^~~~3824:2: note: 'sprintf' output between 2 and 4 bytes into a destination of size 2 sprintf(gain_str, "%d", live_gain-30); 这里 char gain_str[2]={0} 和 unit8_t live_gain=0 已初始化
    • 因为%d printf 格式说明符将在13 字节之间写入2 字节区域。它就在描述中。
    猜你喜欢
    • 2020-10-22
    • 2022-08-06
    • 2021-07-01
    • 2017-04-30
    • 2023-02-17
    • 1970-01-01
    • 2023-01-27
    • 2016-03-14
    • 1970-01-01
    相关资源
    最近更新 更多