Apolyton Archive  |  Preserved copy of the Apolyton Civilization Site and its forums as they stood in September 2005. Read-only; nothing here can be posted to or replied to.  |  Forum index |  About this archive |  The 1998–2001 UBB forums
Today on Apolyton WARDELL INTERVIEW PROMO A.C.S. HISTORY CHAPTER 4 GET CIV4 /w FREE PLUS! A.C.S. PHOTO GALLERY GET A.O.M. V1.1
Apolyton Civilization Forums
main| civ2| civ3| civ4| smac| ctp2| ron| moo3| galciv| galciv2| alt| about|
ApolytonPLUS | register | search | faq | new posts | pm (-/-) | upload | members
hall of fame new! | civgroups | civgroups news | interviews | the column | radio | chat | directory | news | store | PLUS
Apolyton Civilization Forums : Powered by vBulletin version 2.0.3 Apolyton Civilization Forums > Call To Power II > CtP2-Source Code Project > Compiler directives
Show a Printable Version | Email This Page to Someone! | Receive updates to this thread | Report this to Apolyton news!
CivGroups
CTP2 Source Code Project (59): Not a Member - Join

bottom of page
  
Author
Thread    < Last Thread     Next Thread > Post New Thread     Post A Reply
Mirimunchkin is offline Mirimunchkin

Chieftain

Jan 2005
time: 05:19
  Old Post 10-05-2005 03:15
Edit/Delete Message Reply w/Quote
#1 Report this post to a moderator
Compiler directives Help yourself to an AD-FREE life

Can anyone help me with this?

I'm self-teaching myself C++, and browsing the original CtP2 source code files

I understand '#if' statements when they relate to #defined names but keep coming across '#if 0' and '#if 1' (Player.cpp even contains a '#if 0 - #endif' embedded in another '#if 0 - #endif'). As no field is being tested for a value of 0 or 1 just what does this code check?

Txs in advance

PS Martin G, thanks for your advice. I've managed to pick up an unused copy of VS6 on eBay, which I'm also now learning about.

Peter Triggs is offline Peter Triggs
Prince
Gone Fishin, Canada
Jan 2000
time: 05:19
  Old Post 10-05-2005 03:43
Edit/Delete Message Reply w/Quote
#2 Report this post to a moderator
Support Apolyton, buy Civilization III: Complete

For example,

code:
void Player::InsertArmy(const MapPoint &point, const Unit &home_city, Army &army, CAUSE_NEW_ARMY cause) { #if 0 sint32 i, n = army.Num(); static UnitDynamicArray revealed; revealed.Clear(); BOOL revealed_unexplored; for(i = 0; i < n; i++) { army[i].Place(point, home_city); sint32 r = army[i].SetPosition(point, revealed, revealed_unexplored); Assert(r); InsertUnitReference(army[i], cause); } #endif }



Here all the stuff between "#if 0" and "#endif" is 'dead code' (it's unreachable, will never be executed). As I understand it, they used these just like "/*" and "*/" to comment out the intervening code.

But I, too, have a question. There are directives like:

code:
#ifdef _DEBUG_SCHEDULER Assert(m_army->m_theAgent == this); #endif _DEBUG_SCHEDULER


This, I take it is another example of dead code because m_theAgent is not (now) a member of the class Army. So, where would these things be defined when they are defined? And what should we do with them?

Mirimunchkin is offline Mirimunchkin

Chieftain

Jan 2005
time: 05:19
  Old Post 10-05-2005 14:56
Edit/Delete Message Reply w/Quote
#3 Report this post to a moderator
Get a bigger avatar today!

Txs for the reply, Peter.

What you say makes sense, though it's not an application of the compiler directives option that I've ever come across in any other language (that's what was causing my confusion. I expected it to be there for a positive reason).

Re your question - my reading of the various manuals/tutorials that I can access yields -

'#ifdef _DEBUG_SCHEDULER' becomes operative if the preprocessor has previously encountered '#DEFINE bool _DEBUG_SCHEDULER'.

The info on this topic is vague re what specifically is covered by the word 'previously'. I assume at least the file it's referenced in, but what about any others ie '#include' files?

Any of you REAL C++ code-cutters care to join in?

tombom is offline tombom
Chieftain
Pining for the fjords
Oct 2004
time: 05:19
  Old Post 10-05-2005 22:11
Edit/Delete Message Reply w/Quote
#4 Report this post to a moderator
Got spare money?

I'm not a real C++ code-cutter, but still.

Include puts the entire contents of the file to be included in to the including file. So this means that anything in the included file will take effect in the including file. I don't think a define in a different non-included file will count though.

Mirimunchkin is offline Mirimunchkin

Chieftain

Jan 2005
time: 05:19
  Old Post 11-05-2005 21:46
Edit/Delete Message Reply w/Quote
#5 Report this post to a moderator
Avatar Enlargement: We've got the solution

Txs for the info, Tombom.

That confirms what I had surmised from other languages' use of 'include' type functionality. Makes for a fun time when multi-nested Includes are encountered (tops to date is 6 levels).

As Activision's code actually compiled I assume that the C++ compiler can recognise and ignore duplicated Includes.

Simple pseudo xxample -

Program contains

#include a.h
#include b.h

where a.h contains #include b.h

Fromafar is offline Fromafar
Prince

May 2003
time: 06:19
  Old Post 11-05-2005 22:39
Edit/Delete Message Reply w/Quote
#6 Report this post to a moderator
Suffering from ads?

No, the compiler will not recognise this at all, and will happily include b.h twice. That is why most .h-files contain

code:
(1) #ifndef SOME_UNIQUE_SYMBOL (2) #define SOME_UNIQUE_SYMBOL ... (3) #endif // end of file

The first time the compiler goes through this file, it will define SOME_UNIQUE_SYMBOL at (2). The second time the compiler goes through the same file, it will detect at (1) that SOME_UNIQUE_SYMBOL has already been defined, and skip everything until the end (3).

vovan is offline vovan
Emperor

Oct 2001
time: 06:19
  Old Post 11-05-2005 22:50
Edit/Delete Message Reply w/Quote
#7 Report this post to a moderator
Browse Apolyton AD-FREE

quote:
Originally posted by Peter Triggs
Here all the stuff between "#if 0" and "#endif" is 'dead code' (it's unreachable, will never be executed). As I understand it, they used these just like "/*" and "*/" to comment out the intervening code.


You understand correctly, but I think it bears mentioning why that is the case. Back in the days of C (no ++) there was no boolean data type, and in the conditional statements, 0 meant false and anything else (including 1) meant true. Therefore, if you write something like if (0) { ... } then the statements in curly braces denoted by ... will never execute, and if you wrote if (1) { ... } then it will always execute.

Now, the same holds true for #if directives. However, they are not, as you say, compiler directives, but rather preprocessor directives, which basically takes in your source file, processes it, and spits out another text file to the compiler. When it encounters an #if ... #endif directive, it will check whether the conditional is true, and if so will spit the code between the directives unchanged, and otherwise it will just cut it from the file. So essentially, if we have a file that looks like this:

code:
int main() { #if 0 return 0; #else return 1; #endif }


Then the compiler will only see:

code:
int main() { return 1; }


because the preprocessor will cut out the code in the false branch of the #if directive.

Now, the thing to realize here is that it is the proprocessor that does the processing of #blah directives, not the compiler, which means that you cannot do something like this:

code:
int main() { int i = 1; #if (i == 1) printf("eek"); #endif return 0; }


Of course, this is illegal, because the preprocessor knows nothing whatsoever about the code. All it sees is pound signs at the beginning of the line followed by a keyword, and that's all it cares about. Everything else, including the i variable, is just plain text for it.

And this leads up to the next answer:

quote:
Originally posted by Peter Triggs
code:
#ifdef _DEBUG_SCHEDULER Assert(m_army->m_theAgent == this); #endif _DEBUG_SCHEDULER


This, I take it is another example of dead code because m_theAgent is not (now) a member of the class Army. So, where would these things be defined when they are defined? And what should we do with them?


Okay, so #ifdef _DEBUG_SCHEDULER is shorthand for #if defined(_DEBUG_SCHEDULER), and defined(...) is a preprocessor function that returns true if the name in parens is a defined preprocessor symbol (because as I said above, we can't do preprocessing on regular variables). Now, preprocessor symbols can be defined two ways. First, we can issue a preprocessor directive to define a symbol like this:

#define _DEBUG_SCHEDULER

This is most often used to not only define a symbol, but also give it a meaningful value, such as:

#define PI 3.1415926

Now, remember, all the preprocessor deals with is text, so now, whenever it encounters the word PI in your source, it will literally cut out the word PI and past its value, so if you did something like this:

code:
#define PI 3.1415926 int main() { return (int)PI; }


What the compiler would see is simply this:

code:
int main() { return (int) 3.1415926; }


However, for symbols used in conditionals like in the above example, one would usually define a preprocessor symbol by passing it as a parameter to the compiler. To do it in visual studio, go to your project properties, choose the compiler tab, and somewhere in there there is a field where you can define preprocessor symbols (I don't remember precisely where, as I don't have VS handy at the moment). The default ones are usually WIN32 to denote the platform for which we are compiling, _DEBUG or NDEBUG to denote whether we are compiling a debug or release version, and CONSOLE or... something, to denote whether we are building a console app or a windows app.

quote:
Originally posted by Mirimunchkin
As Activision's code actually compiled I assume that the C++ compiler can recognise and ignore duplicated Includes.


Well, actually, you assume wrong. Like I said, as far as the preprocessor is concerned, this stuff is just plain text. So in your example, b.h would actually be included twice. To remedy this problem, what people will do is either use the #pragma once directive (which I *think* is VS-specific, that is, doesn't work with gcc, say, but I might be wrong), or they will do something like this:

#ifndef _BLAH_
#define _BLAH_

...

#endif

That way, the first time we include the file, _BLAH_ is not defined, and therefore everything between the #ifndef ... #endif directives is processed, that is, _BLAH_ is defined, and the rest of the file included. The second time we include the file, _BLAH_ has already been defined, therefore ifndef _BLAH_ evaluates to false and the file is dropped, and not included the second time.

Hope this sheds some light on the problem.

Vovan

Mirimunchkin is offline Mirimunchkin

Chieftain

Jan 2005
time: 05:19
  Old Post 12-05-2005 14:18
Edit/Delete Message Reply w/Quote
#8 Report this post to a moderator
Support Apolyton, buy Civilization 2

Txs, Vovan.
Very, very helpful info.

Mirimunchkin is offline Mirimunchkin

Chieftain

Jan 2005
time: 05:19
  Old Post 13-05-2005 04:17
Edit/Delete Message Reply w/Quote
#9 Report this post to a moderator
Full PM-box? Change here!

Oops. Sorry.
Thank you, Fromafar. Kinda forgot you after working thru Vovan's reply. I've just finished browsing the newdb .h files & they amply illustrate your point.

Martin Gühmann is offline Martin Gühmann
Emperor
Berlin, Germany
Mar 2001
time: 06:19
Post  Old Post 14-05-2005 20:47 Visit Martin Gühmann's homepage!
Edit/Delete Message Reply w/Quote
#10 Report this post to a moderator
Got spare money?

quote:
Originally posted by Mirimunchkin
'#ifdef _DEBUG_SCHEDULER' becomes operative if the preprocessor has previously encountered '#DEFINE bool _DEBUG_SCHEDULER'.


Well of course it should be:

#define _DEBUG_SCHEDULER, #define with small letters it really does matter as C++ is case sensitive and no bool in the middle of the expression. It isn't a variable declaration and only usefull for the preprocessor.

quote:
Originally posted by Peter Triggs
But I, too, have a question. There are directives like:

code:
#ifdef _DEBUG_SCHEDULER Assert(m_army->m_theAgent == this); #endif _DEBUG_SCHEDULER



This, I take it is another example of dead code because m_theAgent is not (now) a member of the class Army. So, where would these things be defined when they are defined? And what should we do with them?


Well the define part is already explained. Actual we can't do much with _DEBUG_SCHEDULER, except removing it entirely. But itsn't used very much so we can leave this work to the preprocessor when we compile the program.

As you already have noticed, this allow us to add to the code a lot of additional code, for debugging purposes without the need to remove everything once the game is done. Actual it is very confortable I can compile a debug version with all the instrumention needed and then a final version without all the slowing stuff. And that works without manual cutting this does the preprocessor for us.

-Martin

  < Last Thread     Next Thread > Post New Thread     Post A Reply
All times are GMT. The time now is 05:19.
Apolyton Time is 00:19.
    top of page
Rate This Thread:
Forum Jump:
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is ON
vB code is ON
Smilies are ON
[IMG] code is ON
 




Contact Us - Apolyton Civilization Site - Support Us!

Building a better Apolyton through better information. Click here and take our poll!
Non-US visitors, click here!

Powered by: vBulletin Version 2.0.3
Copyright ©2000, 2001, Jelsoft Enterprises Limited.

Page generated in 0.0466 seconds (90.25% PHP - 9.75% MySQL) with 36 queries
Page Loading Time:

Support Apolyton: Amazon USA | Amazon UK | Amazon DE | Amazon FR |
Support Apolyton and get FREE PLUS, Buy from Chips&Bits: Galactic Civilizations | Galactic Civilizations: Deluxe Edition | Call to Power 2 | Civilization: The Boardgame | GURPS/ Alpha Centauri | Alpha Centauri | Civilization IV | Civilization III: Complete |


Front Page | Civilization IV | Civilization III | Civilization II | Call to Power II | Alpha Centauri | Master of Orion III
Rise of Nations | Galactic Civilizations | Galactic Civilizations II | Misc
Alt.Civs | Civ I | C:CtP I | About | News | Directory | Apolyton Store | Forums | Chat | Columns | Interviews | Newsletter
Scenario League | CSC | Clash of Civs | Spanish Site | CtP Maps | Cradle of Civ | WesW's Ctp1/2 Site | Civ3 Haven

apolyton.net | apolyton.com | civilization2.net | civilization3.net | civilization4.net | civilizationiv.info | calltopower.net | galciv.net | galciv2.net | moo3.net