这段代码在windows上为什么没有错误?(solaris下有错误)

lw1a2 2008-03-07 10:54:57
代码如下:
//a.h
#ifndef _A_H_
#define _A_H_
void f(int i);
#endif

//a.cpp
#include "a.h"
#include <iostream>

void f(const int i)
{
std::cout << i << std::endl;
}

//main.cpp
#include "a.h"

int main()
{
f(1);
return 0;
}
----------------------------------------------------
编译器信息:
windows:vc2005
solaris:
CC: Sun C++ 5.8 2005/10/13
----------------------------------------------------
solaris下的错误:
bash-3.00# CC -o main main.cpp a.cpp
main.cpp:
a.cpp:
未定义 文件中的
符号 在文件中
void f(int) main.o
ld: 致命的: 符号参照错误. 没有输出被写入main
bash-3.00#



...全文
269 24 打赏 收藏 举报
写回复
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
taodm 2008-03-31
  • 打赏
  • 举报
回复
声明和实现应该保持严格的一致,否则后果自负。
楼主应该牢记教训。
2个编译器的行为都是无可指责的,错误的是写代码的人。
Skt32 2008-03-31
  • 打赏
  • 举报
回复
用过pro*c 没用过“solaris”
lmw110 2008-03-13
  • 打赏
  • 举报
回复
........
mymtom 2008-03-13
  • 打赏
  • 举报
回复
看起来Sun的C++编译器设计得很有特点.
mymtom 2008-03-13
  • 打赏
  • 举报
回复
b.cpp 和 a.cpp唯一的不同是去掉了const.
下面是分别用CC和g++编译后nm出来的输出:
系统和编译器版本:

$ uname -a
SunOS t1000 5.10 Generic_118833-33 sun4v sparc SUNW,Sun-Fire-T1000 Solaris
$ CC -V
CC: Sun C++ 5.8 Patch 121017-02 2006/04/19
$ g++ -v
Using built-in specs.
Target: sparc-sun-solaris2.10
Configured with: /net/tibia/export/bldmstr/nightly/20061019_mars_gcc.s10.opt.tarbuild/src/configure --prefix=/opt/gcc --enable-shared --with-system-zlib --enable-checking=release --disable-libmudflap --enable-languages=c,c++ --enable-version-specific-runtime-libs --with-gxx-include-dir=/opt/gcc/include/c++/4.0.3 --with-cpu=v9
Thread model: posix
gcc version 4.0.3 (gccfss)



[CC -c a.c b.c main.c]
[nm a.o b.o main.o]

a.o:

[Index] Value Size Type Bind Other Shndx Name

[8] | 16| 52|FUNC |GLOB |0 |2 |__1cBf6Fki_v_
[7] | 0| 0|NOTY |GLOB |0 |UNDEF |__1cDstdEcout_
[4] | 16| 56|FUNC |GLOB |0 |4 |__1cDstdEendl4Ccn0ALchar_traits4Cc___6Frn0ANbasic_ostream3CTACTB___4_
[5] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___2l6Mi_r1_
[6] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___2l6MpFr1_2_2_
[3] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___Dput6Mc_r1_
[2] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___Fflush6M_r1_
[1] | 0| 0|FILE |LOCL |0 |ABS |a.cpp


b.o:

[Index] Value Size Type Bind Other Shndx Name

[8] | 16| 52|FUNC |GLOB |0 |2 |__1cBf6Fi_v_
[7] | 0| 0|NOTY |GLOB |0 |UNDEF |__1cDstdEcout_
[4] | 16| 56|FUNC |GLOB |0 |4 |__1cDstdEendl4Ccn0ALchar_traits4Cc___6Frn0ANbasic_ostream3CTACTB___4_
[5] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___2l6Mi_r1_
[6] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___2l6MpFr1_2_2_
[3] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___Dput6Mc_r1_
[2] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___Fflush6M_r1_
[1] | 0| 0|FILE |LOCL |0 |ABS |b.cpp


main.o:

[Index] Value Size Type Bind Other Shndx Name

[2] | 0| 0|FUNC |GLOB |0 |UNDEF |__1cBf6Fi_v_
[4] | 0| 0|NOTY |GLOB |0 |ABS |__fsr_init_value
[3] | 16| 40|FUNC |GLOB |0 |2 |main
[1] | 0| 0|FILE |LOCL |0 |ABS |main.cpp


==============================================================================
[g++ -c a.c b.c main.c]
[nm a.o b.o main.o]

a.o:

[Index] Value Size Type Bind Other Shndx Name

[11] | 0| 0|SECT |LOCL |0 |7 |
[2] | 0| 0|SECT |LOCL |0 |2 |
[3] | 0| 0|SECT |LOCL |0 |3 |
[10] | 0| 0|SECT |LOCL |0 |6 |
[5] | 0| 0|SECT |LOCL |0 |4 |
[12] | 0| 0|SECT |LOCL |0 |8 |
[7] | 0| 0|SECT |LOCL |0 |5 |
[6] | 232| 28|FUNC |LOCL |0 |2 |_GLOBAL__D__Z1fi
[4] | 188| 28|FUNC |LOCL |0 |2 |_GLOBAL__I__Z1fi
[14] | 16| 40|FUNC |GLOB |0 |2 |_Z1fi
[9] | 72| 100|FUNC |LOCL |0 |2 |_Z41__static_initialization_and_destruction_0ii
[16] | 0| 0|FUNC |GLOB |0 |UNDEF |_ZNSolsEPFRSoS_E
[15] | 0| 0|FUNC |GLOB |0 |UNDEF |_ZNSolsEi
[18] | 0| 0|FUNC |GLOB |0 |UNDEF |_ZNSt8ios_base4InitC1Ev
[19] | 0| 0|FUNC |GLOB |0 |UNDEF |_ZNSt8ios_base4InitD1Ev
[13] | 0| 0|OBJT |GLOB |0 |UNDEF |_ZSt4cout
[17] | 0| 0|NOTY |GLOB |0 |UNDEF |_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
[8] | 0| 1|OBJT |LOCL |0 |5 |_ZSt8__ioinit
[20] | 0| 0|NOTY |GLOB |0 |UNDEF |__gxx_personality_v0
[1] | 0| 0|FILE |LOCL |0 |ABS |a.cpp


b.o:

[Index] Value Size Type Bind Other Shndx Name

[11] | 0| 0|SECT |LOCL |0 |7 |
[2] | 0| 0|SECT |LOCL |0 |2 |
[3] | 0| 0|SECT |LOCL |0 |3 |
[10] | 0| 0|SECT |LOCL |0 |6 |
[5] | 0| 0|SECT |LOCL |0 |4 |
[12] | 0| 0|SECT |LOCL |0 |8 |
[7] | 0| 0|SECT |LOCL |0 |5 |
[6] | 232| 28|FUNC |LOCL |0 |2 |_GLOBAL__D__Z1fi
[4] | 188| 28|FUNC |LOCL |0 |2 |_GLOBAL__I__Z1fi
[14] | 16| 40|FUNC |GLOB |0 |2 |_Z1fi
[9] | 72| 100|FUNC |LOCL |0 |2 |_Z41__static_initialization_and_destruction_0ii
[16] | 0| 0|FUNC |GLOB |0 |UNDEF |_ZNSolsEPFRSoS_E
[15] | 0| 0|FUNC |GLOB |0 |UNDEF |_ZNSolsEi
[18] | 0| 0|FUNC |GLOB |0 |UNDEF |_ZNSt8ios_base4InitC1Ev
[19] | 0| 0|FUNC |GLOB |0 |UNDEF |_ZNSt8ios_base4InitD1Ev
[13] | 0| 0|OBJT |GLOB |0 |UNDEF |_ZSt4cout
[17] | 0| 0|NOTY |GLOB |0 |UNDEF |_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
[8] | 0| 1|OBJT |LOCL |0 |5 |_ZSt8__ioinit
[20] | 0| 0|NOTY |GLOB |0 |UNDEF |__gxx_personality_v0
[1] | 0| 0|FILE |LOCL |0 |ABS |b.cpp


main.o:

[Index] Value Size Type Bind Other Shndx Name

[5] | 0| 0|SECT |LOCL |0 |5 |
[2] | 0| 0|SECT |LOCL |0 |2 |
[3] | 0| 0|SECT |LOCL |0 |3 |
[4] | 0| 0|SECT |LOCL |0 |4 |
[7] | 0| 0|FUNC |GLOB |0 |UNDEF |_Z1fi
[8] | 0| 0|NOTY |GLOB |0 |ABS |__fsr_init_value
[9] | 0| 0|NOTY |GLOB |0 |UNDEF |__gxx_personality_v0
[6] | 16| 20|FUNC |GLOB |0 |2 |main
[1] | 0| 0|FILE |LOCL |0 |ABS |main.cpp


看起来是函数名mangle的方式不同引起的: Sun C++ mangle 时对const还加了个k标志.
主要编译器的Name Mingleing例子

Compiler void h(int) void h (int, char) void h(void)
GNU GCC 3.x _Z1hi _Z1hic _Z1hv
GNU GCC 2.9x h__Fi h__Fic h__Fv
Intel C++ 8.0 for Linux _Z1hi _Z1hic _Z1hv
Microsoft VC++ v6/v7 ?h@@YAXH@Z ?h@@YAXHD@Z ?h@@YAXXZ
Borland C++ v3.1 @h$qi @h$qizc @h$qv
OpenVMS C++ V6.5 (ARM mode) H__XI H__XIC H__XV
OpenVMS C++ V6.5 (ANSI mode) CXX$__7H__FI0ARG51T CXX$__7H__FIC26CDH77 CXX$__7H__FV2CB06E8
OpenVMS C++ X7.1 IA-64 CXX$_Z1HI2DSQ26A CXX$_Z1HIC2NP3LI4 CXX$_Z1HV0BCA19V
Digital Mars C++ ?h@@YAXH@Z ?h@@YAXHD@Z ?h@@YAXXZ
SunPro CC __1cBh6Fi_v_ __1cBh6Fic_v_ __1cBh6F_v_
HP aC++ A.05.55 IA-64 _Z1hi _Z1hic _Z1hv
HP aC++ A.03.45 PA-RISC h__Fi h__Fic h__Fv
Tru64 C++ V6.5 (ARM mode) h__Xi h__Xic h__Xv
Tru64 C++ V6.5 (ANSI mode) __7h__Fi __7h__Fic __7h__Fv

上表来自:
http://en.wikipedia.org/wiki/Name_mangling
独孤过儿 2008-03-11
  • 打赏
  • 举报
回复
如果把那个const去掉,编译就通过了,如下:

"a.cpp" 8 lines, 85 characters written
bash-2.03$ uname -a
SunOS wssdev-1 5.8 Generic_117350-12 sun4u sparc SUNW,Ultra-4
bash-2.03$ CC -o main main.cpp a.cpp
main.cpp:
a.cpp:
bash-2.03$ ./main
1
bash-2.03$
lw1a2 2008-03-10
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 Seanxiaoxiao 的回复:]
指针型的参数才能够进行const精确匹配,其他的数据类型是没有办法进行const匹配的,标准里是这样说的
[/Quote]
能否告诉我详细的段落?
Chappell 2008-03-10
  • 打赏
  • 举报
回复
lz有星星,俺不敢乱说话,帮顶
cnzdgs 2008-03-09
  • 打赏
  • 举报
回复
在DLL中这两个函数是怎么写的?
Seanxiaoxiao 2008-03-09
  • 打赏
  • 举报
回复
指针型的参数才能够进行const精确匹配,其他的数据类型是没有办法进行const匹配的,标准里是这样说的
dead_of_winter 2008-03-09
  • 打赏
  • 举报
回复
应该不是操作系统的问题
跟编译器有关系 都换用gcc试试看
lw1a2 2008-03-09
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 cnzdgs 的回复:]
引用 10 楼 lw1a2 的回复:
实际的程序的函数,和我写的这个f的例子差不多

但是,实际的程序中,有f这个函数的工程,是编译成动态库的(-G),这时也没有任何错误

然后主程序动态加载这个,运行到这个函数,程序core了,注释掉就没问题

你的意思是说在Windows下把这段代码做成dll会有问题是吗?这两个f函数具体怎么写?调试跟踪过吗?在VC中如果同时存在这两个函数体编译是不能通过的。
[/Quote]

在windows下做成dll是没问题的
cnzdgs 2008-03-08
  • 打赏
  • 举报
回复
对于函数参数中数值类型参数前面的const,由于其只作用于函数体内,在函数调用时有无const没有任何差别。VC生成目标码时会将其忽略,所以对于void f(int i)和void f(const int i)编译后的函数名都是?f@@YAXH@Z,而void f(int i)只是声明而没有实现,所以自动忽略了。(如果两个函数都有实现则编译会报错)
而solaris下没有忽略void f(int i),而且void f(int i)出现在void f(const int i)之前,所以编译器自动选择了void f(int i),但该函数没有实现,所以报错。
Wolf0403 2008-03-08
  • 打赏
  • 举报
回复
分开编译?交换文件指定顺序?
手边没有 Solaris 系统了。。
ppzzhhsky 2008-03-08
  • 打赏
  • 举报
回复
对于函数参数中数值类型参数前面的const,由于其只作用于函数体内,在函数调用时有无const没有任何差别。VC生成目标码时会将其忽略,所以对于void f(int i)和void f(const int i)编译后的函数名都是?f@@YAXH@Z,而void f(int i)只是声明而没有实现,所以自动忽略了。(如果两个函数都有实现则编译会报错)
而solaris下没有忽略void f(int i),而且void f(int i)出现在void f(const int i)之前,所以编译器自动选择了void f(int i),但该函数没有实现,所以报错
cnzdgs 2008-03-08
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lw1a2 的回复:]
实际的程序的函数,和我写的这个f的例子差不多

但是,实际的程序中,有f这个函数的工程,是编译成动态库的(-G),这时也没有任何错误

然后主程序动态加载这个,运行到这个函数,程序core了,注释掉就没问题
[/Quote]
你的意思是说在Windows下把这段代码做成dll会有问题是吗?这两个f函数具体怎么写?调试跟踪过吗?在VC中如果同时存在这两个函数体编译是不能通过的。
lw1a2 2008-03-08
  • 打赏
  • 举报
回复
实际的程序的函数,和我写的这个f的例子差不多

但是,实际的程序中,有f这个函数的工程,是编译成动态库的(-G),这时也没有任何错误

然后主程序动态加载这个,运行到这个函数,程序core了,注释掉就没问题

eDis0n 2008-03-07
  • 打赏
  • 举报
回复
这个应该是编译器设计思想上的一些不同造成了。
在VS2005中,编译器认为

void f(int i);



void f(const int i)
{
std::cout < < i < < std::endl;
}


应该指的一个函数原型,因为在这里对参数int 改为const int型 其实在编译和运行阶段是没有任何差别的,因为本来就是传值调用(传递进去的是i一个副本),所以不管你加还是不加这个const 原来的变量i都是无法改变的,也就是说函数参数是 const int 还是 int 根本就是一会事。
那么作为编译器的设计可能就觉得这里的 const 并不影响到函数原型,那么自然就无法构成函数重载了。 所以在vs2005下编译通过并能够运行。

这只是我根据编译原理和c++语言的特点的一些个人的感觉,不知道对不对,改天我去问问我们c++高级编程的老师看看。

(至于在solaris下的问题,因为没有用过,所以没有发言权哈 o(∩_∩)o)
ryfdizuo 2008-03-07
  • 打赏
  • 举报
回复
@_@
吃了一根大葱 2008-03-07
  • 打赏
  • 举报
回复
确实这样 声明定义不一样!!!
加载更多回复(4)
相关推荐
发帖
C++ 语言

6.3w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
帖子事件
创建了帖子
2008-03-07 10:54
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下