Chinaunix首页 | 论坛 | 博客
  • 博客访问: 389083
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-10 08:38
文章分类
文章存档

2016年(32)

2015年(48)

我的朋友

分类: LINUX

2016-01-08 14:58:15

今天用makefile, g++编译某个问题时遇到这么一个问题:
    .a库里面包含一个fun函数, 但是这个fun函数有两个定义的实现, 而且它的实现是被放在了fun.h中, 两个实现分别被宏marco1和宏macro2区分, 如下:
fun.h:
    class instance{
    private:
        int a;
    public:
          #if defined(marco1)
            int fun(int n){return n;}
         #elif defined(marco2)
           int fun(int n){return n+1;}
         #endif
    };
     在编译生成.a的时候,makefile中定义了宏-Dmarco1.
现在问题来了,我需要生成一个可执行文件main.bin,有一个main.cpp, 并且main.cpp中包含了#include fun.h, main函数需要引用这个.a中的fun, 能否直接这么玩?:
    g++ main.cpp **.a -o main.bin
答案是否定的, 因为会报个这样的错误:说fun未定义!!!why?: 因为你在编译main.bin的时候,并没有定义任何宏呀,所以在编译.bin这个section的时候, 里面是没有任何fun定义的. 可能你会问, 那我.a里面已经定义了一个宏-Dmarco1的呀, .a里面应该是有一个fun的定义的呀. 但是切记, 编译器定义的宏, 是严格跟随文件走的!
    怎么理解编译器定义的宏, 是严格跟随文件走的这句话呢, 就是说, 在编译.a的时候, 里面确实有定义宏-Dmarco1, 那么在.a里面, 确实存在着这么一个fun的定义, 但是因为在生成main.bin的时候, 因为main.cpp中包含了#include fun.h这句话, 那么编译器相当于在编译main.cpp的时候, 把#include fun.h展开了, 而且g++ main.cpp **.a -o main.bin在编译main.cpp的时候, 并没有包含宏-Dmarco1, 它就认为fun没有定义, 而且这里为什么说是宏是严格跟随文件走, 是因为即使在编.a的时候, 定义过宏-Dmarco1, 但是这个宏并不是跟随main.cpp走的, 因此在编译main.cpp的时候就认为没有这个定义.
  
   那么, 能否这么玩呢? 虽然.a的库中定义了宏-Dmarco1, 但是我编.bin的时候却定义了宏-Dmarco2,如下:
    g++ main.cpp **.a -Dmarco2 -o main.bin
这个是可以滴:
这样的话, 你会发现宏-Dmarco2覆盖了宏-Dmarco1, 在main函数中调fun()的时候, 它返回的是-Dmarco2中括起来的函数, 即会返回n+1. 还是遵循"编译器定义的宏, 是严格跟随文件走的"这个定律, 因为编main.cpp, 跟随了一个-Dmarco2, 这样, 即使编.a的时候定义了宏-Dmarco1, 但这个宏不是跟随main.cpp的, 因此没起作用, 被-Dmarco2覆盖了.

再把文件改成下面这样, 把fun的定义和声明分开, 声明依然放在类里, 定义放在cpp里面:
 
fun.h:
    class instance{
    private:
        int a;
    public:        
           int fun(int n);
    };

fun.cpp:
 #if defined(marco1)
   int fun(int n){return n;}
 #elif defined(marco2)
   int fun(int n){return n+1;}
 #endif      
这个时候, 仍然在编.a的时候, 定义宏-Dmarco1,  编main.bin的时候, 定义宏-Dmarco2, 这个时候在main中再调用fun的时候, 会发现返回的是-Dmarco1扩住的函数, 因为在编main.cpp的时候, 虽然定义了宏-Dmarco2, 但因为fun.h中并没有对这个宏的引用, main.cpp包含了fun.h, 经扩展后的文件里面没有宏-Dmarco2, 所以定义的-Dmarco2并没有跟着文件走,   跟着文件走的是-Dmarco1, 所以最后返回的调用函数是被宏-Dmarco1括起来的fun.
阅读(4744) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~