我的问题类似于Different format of __DATE__ macro
但是那里提到的解决方案在我的VS 2013编译器中显示错误。

我只想从日期宏中提取年份,以便制作一个包含类似字符串的宏

#define BUILD_YEAR_CH0 (__DATE__[ 7])
#define BUILD_YEAR_CH1 (__DATE__[ 8])
#define BUILD_YEAR_CH2 (__DATE__[ 9])
#define BUILD_YEAR_CH3 (__DATE__[ 10])

#define COPY "Copyright"

#define COMPANY "ABCD Lmtd"

#define CYC BUILD_YEAR_CH0 BUILD_YEAR_CH1 BUILD_YEAR_CH2 COMPANY

这样我就可以在需要的地方使用CYC宏打印连接的字符串。

但是一旦我在CYC宏中使用BUILD_YEAR_CH0宏/ token ,它就会显示错误。

我也曾尝试制作一个const char缓冲区,它具有确切的年份值,例如
const char MYEAR[] = { __DATE__[7], __DATE__[8],__DATE__[9],__DATE__[10],'\0' };

但是同样,我无法在CYC宏中使用它。
真的仅通过宏而不使用任何变量来完成此操作是真的吗?

最佳答案

__DATE__宏扩展为11字节的字符串文字,格式为"Mmm dd yyyy"。您可以初始化一个字符串指针以指向此文字的第8个字节,以后可以将其用作4字节的C字符串,并带有编译日期的年部分。该指针可以是本地的或全局的,可以自动或静态存储:

#include <stdio.h>

int main(void) {
    const char *build_year = __DATE__ + 7;

    printf("This program was compiled in %s\n", build_year);
    return 0;
}

您甚至可以在宏中使用此方法:
#define BUILD_YEAR  (__DATE__ + 7)

笔记:
  • clang在使用-Weverything编译以上代码时发出警告:
    ctyear.c:4:37: warning: expansion of date or time macro is not reproducible [-Wdate-time]
    

    您可以使用-Wno-date-time禁用此警告。
  • 不幸的是,这种方法不能用于__DATE__宏的其他部分。


  • 编辑:也可以在Makefile中定义宏。使用这种方法,您可以完全控制要在扩展中包括哪些字段:
    ctyear: ctyear.c
        clang '-DBUILD_YEAR="$(shell date +%Y)"' $< -o $@
    

    ctyear.c :
    #include <stdio.h>
    
    #define COMPANY  "Newco"
    #define CYC BUILD_YEAR " " COMPANY
    
    int main(void) {
        printf("Copyright %s\n", CYC);
        return 0;
    }
    

    如果您的大型项目包含许多源文件,则可能有一个Makefile,可以将'-DBUILD_YEAR="$(shell date +%Y)"'添加到CFLAGS的定义中。

    09-05 21:57