Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » general questions on cpp

This thread is locked; no one can reply to it. rss feed Print
general questions on cpp
Bob Keane
Member #7,342
June 2006

While perusing the Exile source codes, I noticed a program file included a header file twice. I have no formal training in cpp and was wondering why. I am thinking if there are two files with the same name but different code, a conflict may occur or data may change causing unexpected results. Also, if there is only one header file with the name, why would it be included twice?

By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul.
"Love thy neighbor as much as you love yourself means be nice to the people next door. Everyone else can go to hell. Missy Cooper.
The advantage to learning something on your own is that there is no one there to tell you something can't be done.

MiquelFire
Member #3,110
January 2003
avatar

I would think it being included twice in a file is a mistake, one that went unnoticed because of header protection doing its job.

As for two files with the same name, depends on how that happened in the first place. If it's from two libraries or one from a library and another from the code you wrote, hopefully, the header protect has the library's name in the #define to allow other libraries (or even the caller's code) to use the same name.

---
Febreze (and other air fresheners actually) is just below perfumes/colognes, and that's just below dead skunks in terms of smells that offend my nose.
MiquelFire.red
If anyone is of the opinion that there is no systemic racism in America, they're either blind, stupid, or racist too. ~Edgar Reynaldo

relpatseht
Member #5,034
September 2004
avatar

Probably a macro trick. You see it for enums often. The header file just lists a bunch of macro calls over symbols ( X( FOO ), X( BAR ), ... ). Then the source files #define and #undef "X" to do different things, like make an enum, then make a char* array.

Chris Katko
Member #1,881
January 2002
avatar

Exile. Retro man. =D

I think you'd have to give us a more specific example to narrow it down. The preprocessor is stupid and people abuse it in a variety of ways.

In a related note: I managed to fix a bug in a 25 year old game, the opensource version of Gladiator. :)

Are you talking about Blades of Exile? Also, wow, 1900 commits on an ancient game. I love people.

https://github.com/calref/cboe/

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Bob Keane
Member #7,342
June 2006

The version of Exile I am referring to is the download. A specific example is in Startup.cpp. I don't remember which header file is referenced to twice, I'll post the code later. Someone recently posted an open source version of the game, so its not surprising people still play it. Chris, I'm surprised you answered this thread since it is in regards to cpp and you are an adherent to D.

<edit>Here is startup.cpp:

#SelectExpand
1 2#include <Windows.h> 3#include "stdio.h" 4 5#include "global.h" 6#include "newgraph.h" 7#include "graphics.h" 8#include "fileio.h" 9#include "actions.h" 10#include "dlgutils.h" 11#include "text.h" 12#include "gutils.h" 13#include "items.h" 14#include "party.h" 15#include "exlsound.h" 16#include "startup.h" 17#include "exlsound.h" 18 19extern party_record_type far party; 20extern pc_record_type far adven[6]; 21extern scen_header_type scen_headers[25]; 22extern Boolean unreg_party_in_scen_not_check; 23extern Boolean in_startup_mode,registered,play_sounds,party_in_memory; 24extern long register_flag; 25extern HWND mainPtr; 26extern short ulx,uly; 27 extern piles_of_stuff_dumping_type *data_store; 28extern piles_of_stuff_dumping_type2 *data_store2; 29 30 31//void start_game(); 32 33RECT startup_button[6]; 34 35Boolean handle_startup_press(POINT the_point) 36{ 37 38 short i,scen; 39 long dummy; 40 41 the_point.x -= ulx; 42 the_point.y -= uly; 43 44 for (i = 0; i < 5; i++) 45 if (PtInRect(&startup_button[i],the_point) == TRUE) { 46// flash_round_rect(start_button_rects[i],10); 47 //OffsetRect(&start_button_rects[i],ul.h,ul.v); 48 //startup_button_click(start_button_rects[i]); 49 50 draw_start_button(i,5); 51 if (play_sounds == TRUE) 52 play_sound(37); 53 else Delay(5,&dummy); 54 draw_start_button(i,0); 55 switch (i) { 56 case 0: 57 startup_load(); 58 break; 59 60 case 1: 61 draw_startup(0); 62 start_new_game(); 63 update_pc_graphics(); 64 draw_startup(0); 65 break; 66 67 case 2: 68 give_reg_info(); 69 draw_startup(0); 70 break; 71 72 case 3: 73 if (party_in_memory == FALSE) { 74 FCD(867,0); 75 break; 76 } 77 scen = pick_prefab_scen(); 78 if (scen < 0) 79 break; 80 if ((registered == FALSE) && (scen > 0)) { 81 FCD(913,0); 82 break; 83 } 84 85 switch (scen) { 86 case 0: sprintf(party.scen_name,"valleydy.exs"); break; 87 // if not reg, rub out 88 case 1: sprintf(party.scen_name,"stealth.exs"); break; 89 case 2: sprintf(party.scen_name,"zakhazi.exs"); break; 90 } 91 put_party_in_scen(); 92 break; 93 94 case 4: // intro 95 if (party_in_memory == FALSE) { 96 FCD(867,0); 97 break; 98 } 99 if (registered == FALSE) { 100 FCD(913,0); 101 break; 102 } 103 // if not reg, rub out 104 105 scen = pick_a_scen(); 106 if (scen_headers[scen].prog_make_ver[0] >= 2) { 107 FCD(912,0); 108 break; 109 } 110 if (scen >= 0) { 111 if (registered == FALSE) 112 unreg_party_in_scen_not_check = TRUE; 113 sprintf(party.scen_name,"%s",data_store2->scen_names[scen]); 114 put_party_in_scen(); 115 } 116 117 break; 118 119 case 5: 120 Delay(50,&dummy); 121 return TRUE; 122 break; 123 124 } 125 } 126 return FALSE; 127} 128/* 129void start_game () 130{ 131 init_party(0); 132 133 setup_outdoors(party.p_loc); 134 135 load_area_graphics(); 136 137 draw_main_screen(); 138 139 in_startup_mode = FALSE; 140 141 adjust_monst_menu(); 142 adjust_spell_menus(); 143 144}*/ 145 146void startup_load()//// 147{ 148 load_file(); 149 update_pc_graphics(); 150 if (in_startup_mode == FALSE) { 151 //end_anim(); 152 end_startup(); 153 post_load(); 154 } 155 else { 156 menu_activate(0); 157 draw_startup(0); 158 } 159 160}

Here is the duplicated header:

void move_sound(unsigned char ter,short step);
void flip_sound();
void clear_sound_memory();
void one_sound(short which);
void force_play_sound(short which);
void play_sound(short which) ;
void load_sounds ();
Boolean sound_going(short which_s);
void incidental_noises();
void sound_pause(long len);
void kill_sound();

If it was a macro trick, what is it supposed to do? What problem would it solve? Whynwould anyone use it?

By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul.
"Love thy neighbor as much as you love yourself means be nice to the people next door. Everyone else can go to hell. Missy Cooper.
The advantage to learning something on your own is that there is no one there to tell you something can't be done.

Chris Katko
Member #1,881
January 2002
avatar

That just looks like a bug. With header guards it'll just be included once.

I assumed you had some wierd "include at top of file" and then later included like 300 lines after some functions.

If you can compile it, simply remove the line and see if it breaks. If it DOES break, then definitely figure it out and tell us! But it's 95% likely just a mistake.

Bob Keane said:

Chris, I'm surprised you answered this thread since it is in regards to cpp and you are an adherent to D.

I use whatever the project requires me to. I wouldn't exactly be hireable if I relegated myself to just D.

Best advice I can give for reading old code: Don't assume the programmer actually knew what they were doing.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Chris Katko
Member #1,881
January 2002
avatar

Use with discretion.

Or never. ;)

Macro trickery (with maybe exception of C library programmers, or special embedded cases) is super frowned upon and will get you "not hired" because it's so potentially evil for modest gains. The reason being, that I mentioned before, is the macro preprocessor is a simple text substitutor that runs before the compiler ever sees the code so it can literally make the code you see, and the code the compiler sees, completely different--making debugging a nightmare.

Over "template magic" use in C++ is also frowned upon in places where performance actually matters because it explodes compile time, and because C++ templates were basically designed by the devil, they can only be understood by "template wizards" on the team. Mike Acton of Insomniac Games straight up said "If I see you using templates, my eye will be raised. If I see you using lots of them, we're going to have a talk."

D templates are a thousand times more readable and powerful (ha! brought it back to D!). But still last a lot of compile time unless you toss them into specific object files so they don't retrigger every compile.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Bob Keane
Member #7,342
June 2006

Chris said:

If you can compile it, simply remove the line and see if it breaks. If it DOES break, then definitely figure it out and tell us! But it's 95% likely just a mistake.

I think it will be years before I can compile it. It seems weird the language would have like this in it when everyone says it is so dangerous.

By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul.
"Love thy neighbor as much as you love yourself means be nice to the people next door. Everyone else can go to hell. Missy Cooper.
The advantage to learning something on your own is that there is no one there to tell you something can't be done.

Chris Katko
Member #1,881
January 2002
avatar

???

When C was written, it was the 60's into the 70's. OOP wasn't invented yet. They didn't know obvious coding truths we have today. Just like how Java was "the language" in the 90's and now is pretty dead except for corporate installations because people realized it wasn't as productive as promised and full of boilerplate, and the JVM wasn't the "one code runs everywhere" zen future everyone thought it was going to be--it turns out different platforms have different requirements and a JVM can't magically re-write all your code to run efficiently on an embedded machine, a 128-core server, and a desktop. It's still "good" it just wasn't "as game changing as promised". Now nobody teaches Java in schools. It's mostly Python, Javascript, and... I would hope, C#.

Anyhow, goto statements are heavily frowned upon because more often than not, if you see one, the developer used it not because they knew what they were doing, but the far opposite, they didn't understand at all the implications.

Likewise, macros. They're not "as evil" as my previous hyperbole implies. They have more uses than goto. You can make little fake templates like ADD(x,y) which takes any integer/float type, without manually writing 15 different combinations for the same function. But they have no static, compile-time checking.* Which is the entire purpose of C/C++/etc. The static type checking is what protects you. So if you're willing to take a calculated risk (when the developer is smart), macros can be useful. But anyone who doesn't know "exactly" what they're doing, shouldn't be throwing them in to production code unless they're willing to enter the possibility of long debugging sessions.

(*the resulting code is type checked. But the preprocessor itself isn't. It doesn't know what an integer is. It just knows "replace this string with this string".)

C is mostly unchanged language from C99. It's used in tons of embedded settings and nobody wants to break old code.

C++ to it's credit, over the last decade, has been actively depreciating old code. The old code still works (you can compile in an old standard of C++ even with a new compiler) so it doesn't break the billions of lines of code already running in old installations. But you can still write better code.

But I would argue that the majority of seasoned C coders already know about the "gotchas" of C (especially because it's a relatively simple language) so they don't need to remove things like macros or goto statements. Specialized tools should be used for specialized jobs. It doesn't make the tool evil, it's what you do with it. A macro type nail, use a macro type hammer. Any replacement of oldschool C constructs like macros would likely introduce tons of new problems.

The thing is with games: It doesn't matter if you have perfect code, all that matters is you ship the game. Many open sourced games (like glad) were written by teens or young adults in college by junior programmers learning as they went.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

relpatseht
Member #5,034
September 2004
avatar

Mike Acton of Insomniac Games straight up said "If I see you using templates, my eye will be raised. If I see you using lots of them, we're going to have a talk."


It's funny you say this, because Acton is a big proponent of macros and even custom preprocessing tools to do template like things.

Chris Katko
Member #1,881
January 2002
avatar

Yeah, they're way faster than templates. You just have to know what you're actually doing and ensure through coding standards that your programmers do too.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Go to: