在不同的系统上编译相同的程序会产生不同的结果吗?

标签 c date gcc printf

这是程序:

#include <stdio.h>
#include <libgen.h>
#include <stdlib.h>
#include <time.h>

#define DATE_SIZE   10

// Declare global variables.
char *program_name = NULL;

int main (int argc, char *argv[])
{
// Declare variables.
    time_t t = time(NULL);
    struct tm tm = *localtime(&t);
    char date[DATE_SIZE + 1] = {0};

// Store today's date in a string for comparison.
    if(sprintf(date, "%d/%d/%d", tm.tm_mon + 1, tm.tm_mday, tm.tm_year - 100) < 0)
    {
        fprintf(stderr, "%s: main error: sprintf failed.\n", program_name);
        exit(EXIT_FAILURE);
    }

// Print date to user.
    printf("Date: %s\n", date);

// Exit gracefully.
    exit(EXIT_SUCCESS);
}

它是用以下内容编译的:

gcc -Wall -Werror -O3 -o program program.c

我还有 2 台机器都运行 Arch linux:

Linux laptop 4.15.7-1-ARCH #1 SMP PREEMPT Wed Feb 28 19:01:57 UTC 2018 x86_64 GNU/Linux

Linux storage 4.14.66-1-ARCH #1 SMP Sat Aug 25 01:09:50 UTC 2018 armv6l GNU/Linux

当我在笔记本电脑上编译时,它很干净并且运行完美。当我在存储服务器上编译时,出现以下错误:

program.c: In function 'main':
program.c:20:5: error: '/' directive writing 1 byte into a region of size between 0 and 10 [-Werror=format-overflow=]
  if(sprintf(date, "%d/%d/%d", tm.tm_mon + 1, tm.tm_mday, tm.tm_year - 100) < 0)
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
program.c:20:5: note: directive argument in the range [-2147483648, 2147483547]
program.c:20:5: note: 'sprintf' output between 6 and 36 bytes into a destination of size 11
cc1: all warnings being treated as errors

为什么会有差异?

更新

<小时/>

所有评论似乎都在讨论如何修复错误。首先,您需要知道这是一个最小化的程序。我创建的日期与我未创建的另一个日期进行比较。因此采用 mm/dd/yy 格式。此外,大多数名称中包含“n”的函数(strncpy、snprintf...)适用于您不知道数据或数据是用户生成的情况。我将其视为惰性编程,因为您不知道正在使用的数据。另外,我知道这个程序 82 年内不会被使用。

不,我的问题必须处理编译结果的差异。

最佳答案

正如 Osiris 所说,sprintf() 可能会向 date 写入超过 DATE_SIZE+1 个字节。

如果你想存储文件名,我建议使用 FILENAME_MAX对于缓冲区的大小——保证足够大

此外,使用snprintf()来限制写入缓冲区的字符数量。这可以避免内存管理问题,在其他情况下可能会导致安全漏洞。

检查 snprintf() 的返回值并确认整个字符串已被写入(即您的日期足够大。

char date[FILENAME_MAX];
int rv = sprintf(date, sizeof(date), "%d/%d/%d",
                 tm.tm_mon + 1, tm.tm_mday, tm.tm_year - 100);
if (rv < 0) printf("encoding error\n");
if (rv == sizeof(date)) printf("not big enough\n");

关于在不同的系统上编译相同的程序会产生不同的结果吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52066849/

相关文章:

python - 将 DataFrame 中的困惑日期字符串转换为 python 和 pandas 中的 `datetime`

c - 为不存在的函数声明函数原型(prototype)是否安全?

gcc - gcc和clang在编译时给我一个错误

c - -Werror 导致编译器在#warning 处停止。我能做些什么来防止这种情况发生?

c - (伪)C 中的 OOP 从其函数指针获取结构对象

c - 如何编写unix "time"之类的实用程序

c - string转int编译报错怎么解决?

c - 处理器行为解释

python - 如何使用 pandas 按组减去基于数据的列的行?

date - TryStrToDate 失败,格式为 mmm/yy