如果C++的inline函数中有宏,行为是怎样的?

查看:92
本文介绍了如果C++的inline函数中有宏,行为是怎样的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

这里是几份C++代码:

a.h

#include <iostream>
#ifndef STR
#define STR "default"
#endif

struct A {
    static void print() { std::cout << STR; }
};

imp1.cc

#define STR "imp1"
#include "a.h"
void imp1() { A::print(); }

imp2.cc

#define STR "imp2"
#include "a.h"
void imp2() { A::print(); }

main.cc

void imp1();
void imp2();
int main() { imp1(); imp2(); }

我们知道,在类定义中定义的函数默认是inline函数,inline函数将建议编译器在行内展开代码。那么main打印的是imp1, imp2还是str?

我找不到相关的资料。相同的代码,编译命令为g++ main.cc imp1.cc imp2.cc时,在GCC 6.1.1上面是打印imp1imp2,在MinGW GCC 4.8.1上面是打印imp1imp1。在编译命令为g++ imp2.cc imp1.cc main.cc,在GCC 6.1.1上面没有变化,在MinGW GCC 4.8.1上面是打印imp2imp2

请问C++ standard有相关规定(也就是说是MinGW的bug),还是未定义行为呢?

解决方案

试了一下,gcc 如果 -O2 或者 -O1 优化,出来的结果 imp1imp2 这样的,如果是 -O0 优化,出来的 imp1imp1 或者 imp2imp2

原因应该是在没有 -O 优化的情况下 inline 会被 gcc 忽略,以方便调试。

标准里 inline 应该是一个 suggestion,而不是一个强制的要求。如果没有 inline,.o 文件的顺序就成了决定性因素。

$ gcc -v
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/lto-wrapper
目标:x86_64-pc-linux-gnu
配置为:/build/gcc-multilib/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release
线程模型:posix
gcc 版本 6.1.1 20160802 (GCC) 

这篇关于如果C++的inline函数中有宏,行为是怎样的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆