|
阅读:1399回复:11
恐怖C++
偶然见到了这样一段代码:
第一感觉是编译通不过,前面已经将SomeFunction定义成为一个函数指针,后面在类中的定义有重名的嫌疑。 试了一下,还真编译过去了。按照kmwang的解释,类中的定义名称为:SomeClass::SomeFunction; 在想想那个typedef不是没用么?要用上的话代码应该如下:
再想想,既然类中成员的名字和Typedef的名字不会重复,那么是不是可以这样:
在VC++6.0上编译了一下竟然通过!恐怖!不知道是不是BS所谓的“未定义行为”。 [ 2004-07-03 02:03:58 ApH 修改 ] |
|
|
1C#
发布于:2004-07-02 00:05
Re:恐怖C++
哦,我的天啊,还可以这样的?真晕了
--------------------
我就是我,松柏! |
|
|
|
2C#
发布于:2004-07-02 10:42
Re:恐怖C++
学C#呢,C语言100例改成C#的,学着感觉很好很有用,遇到问题,然后找解决方法,对初学者来说真的非常有帮助。
[a]http://210.32.80.26/teacher/yjj/cpp/经典C程序100例.htm[/a] -------------------- -------------------------------------------------------------------------- 一个人的尊严和人格是绝对神圣而不可侵犯的 如若有歹人敢亵渎之,则必以天赋之自卫权利以应之! -----[精武英雄] 注意:此人偶尔会使用不文明语言!! -------------------------------------------------------------------------- 传说中的最强ID! [a]http://1319.nease.net[/a] |
|
|
|
3C#
发布于:2004-07-02 11:02
|
|
|
|
4C#
发布于:2004-07-02 11:20
Re:恐怖C++
我覺得這是C++編譯器預處理identifier的事情.
首先它不會把 #define A B 的class ABC替換成爲class BBC. 不是麽?因爲ABC和A是不同的ID. typedef也是一樣.成員函數(/變量)首先已加過名字替換,並不是表面看來的Something,而是ClassABC@@SomethingIntChar.所以typedef是處理不了這樣子的名字的. 而聲明的類型將會被替換掉的。 [ 2004-07-02 23:11:47 mumu 修改 ] |
|
|
|
5C#
发布于:2004-07-02 16:24
Re:恐怖C++
我覺得這是C++編譯器預處理identifier的事情. a mu, 你的解释很清晰啊:) i have another question, In file suffix.hpp there are lines: #define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) #define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y) #define BOOST_DO_JOIN2( X, Y ) X##Y why donot we define such macro instead: #define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) #define BOOST_DO_JOIN( X, Y ) X##Y |
|
|
|
6C#
发布于:2004-07-02 17:25
Re:恐怖C++
==================== //file : test.cpp #if 1 //replaced it by 0 #define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) #define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y) #define BOOST_DO_JOIN2( X, Y ) X##Y #else #define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) #define BOOST_DO_JOIN( X, Y ) X##Y #endif int main(void) { BOOST_JOIN( 1, 2 ); BOOST_JOIN( "abc", "def" ); return 0; } c:\>cl /E test.cpp 結果完全一樣. 我覺得它是考慮到設計的需要吧.我不知道它爲何寫成這樣. |
|
|
|
7C#
发布于:2004-07-02 17:28
Re:恐怖C++
有些變態的寫法是爲了兼容編譯器.
這樣寫可能在複雜語法層次上會帶來好處. |
|
|
|
8C#
发布于:2004-07-02 23:15
Re:恐怖C++
唉,C++太複雜了,弟兄們有時間玩玩PYTHON,多少是一種解脫:)
C+C++的類型檢查真是好,所以大系統必不可少。 底層控制又那麽直接,系統級開發是夠爽。 可是,有誰能證明,PYTHON+C結合就不爽呢? |
|
|
|
9C#
发布于:2004-07-04 23:55
Re:恐怖C++
to:铁板
这两种宏的定义应当是不同的,C++的标准刚出来的时候看过,关键是双替换列表的识别问题,哪个BOOST_DO_JOIN够变态,应当是应付BOOT_JOIN(X,Y)中x or y也是变态宏的情况.这个例子我得想想,有趣的是gcc的预编译器似乎并不标准,等有空了上vc试验一把.我曾经遇到过在gcc下可以,可在vc下无法进行宏替换的问题,当时解决了一把也没注意. 我算看出来了,你们两个要是当C++教师,怕是整个中国没人能考及格. |
|
|
10C#
发布于:2004-07-22 23:31
Re:恐怖C++
那天和APH讨论了一下,原来没看清,作者梦游时写的代码:)
二次展开已经很严密,没有三次展开的概念. |
|
|
11C#
发布于:2005-06-25 09:13
Re:恐怖C++
我覺得這是C++編譯器預處理identifier的事情.首先它不會把#define A B的class ABC替換成爲class BBC.不是麽?因爲ABC和A是不同的ID.typedef也是一樣.成員函數(/變量)首先已加過名字替換,並不是表面看來的Something.. 我觉得这主要是和作用域有关系: typedef int a; // int a = 0; 错误 long b = 0; int main() { typedef char a; typedef a b; // typedef int b;错误 a c = 0; b g = 4; { typedef int b; a a = 1; b i = 2; { int a = 5; b b = 2; } a = 5; { char a = 1; float b = 2; } } b h = 9; a f =8; return 0; } 这段代码也可以在VC6.0编译通过,它的汇编代码如下: TITLE G:\atest\main.cpp .386P include listing.inc if @Version gt 510 .model FLAT else _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' _TEXT ENDS _DATA SEGMENT DWORD USE32 PUBLIC 'DATA' _DATA ENDS CONST SEGMENT DWORD USE32 PUBLIC 'CONST' CONST ENDS _BSS SEGMENT DWORD USE32 PUBLIC 'BSS' _BSS ENDS $$SYMBOLS SEGMENT BYTE USE32 'DEBSYM' $$SYMBOLS ENDS $$TYPES SEGMENT BYTE USE32 'DEBTYP' $$TYPES ENDS _TLS SEGMENT DWORD USE32 PUBLIC 'TLS' _TLS ENDS ; COMDAT _main _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' _TEXT ENDS FLAT GROUP _DATA, CONST, _BSS ASSUME CS: FLAT, DS: FLAT, SS: FLAT endif PUBLIC ?b@@3JA ; b _BSS SEGMENT ?b@@3JA DD 01H DUP (?) ; b _BSS ENDS PUBLIC _main EXTRN __fltused:NEAR ; COMDAT _main _TEXT SEGMENT _c$ = -4 _g$ = -8 _a$223 = -12 _i$224 = -16 _a$225 = -20 _b$226 = -24 _a$227 = -28 _b$228 = -32 _h$ = -36 _f$ = -40 _main PROC NEAR ; COMDAT ; 6 : { push ebp mov ebp, esp sub esp, 104 ; 00000068H push ebx push esi push edi lea edi, DWORD PTR [ebp-104] mov ecx, 26 ; 0000001aH mov eax, -858993460 ; ccccccccH rep stosd ; 7 : typedef char a; ; 8 : typedef a b; ; 9 : // typedef int b; ; 10 : a c = 0; mov BYTE PTR _c$[ebp], 0 ; 11 : b g = 4; mov BYTE PTR _g$[ebp], 4 ; 13 : typedef int b; ; 14 : a a = 1; mov BYTE PTR _a$223[ebp], 1 ; 15 : b i = 2; mov DWORD PTR _i$224[ebp], 2 ; 17 : int a = 5; mov DWORD PTR _a$225[ebp], 5 ; 18 : b b = 2; mov DWORD PTR _b$226[ebp], 2 ; 20 : a = 5; mov BYTE PTR _a$223[ebp], 5 ; 22 : char a = 1; mov BYTE PTR _a$227[ebp], 1 ; 23 : float b = 2; mov DWORD PTR _b$228[ebp], 1073741824 ; 40000000H ; 26 : b h = 9; mov BYTE PTR _h$[ebp], 9 ; 27 : a f =8; mov BYTE PTR _f$[ebp], 8 ; 28 : return 0; xor eax, eax ; 29 : } pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END [ 2005-06-25 09:14:32 119 修改 ] |
|
|