 |
 |
 |
 |
|
 |
 |
|
 |
 |
| Author |
Message |
Marilla
Joined: 02 Feb 2006 Posts: 329
|
Posted: Sat Nov 04, 2006 7:26 pm Post subject: |
|
|
CWO's A: is right on the mark; You should -never- declare the same constants in multiple files. Unfortunately, not all scripters have done this; specifically, many scripters will purposefully declare a constant in one file to avoid having to include another file. Personally, I think that's missing the point of includes and constants in the first place (to have 'magic' values set in one, central location so that you can change the values but only need to do so in one place)
You can avoid declaring the same const twice using one of two methods:
1) Declare the const only ever in one file, and include that file in ALL scripts that need that constant, no matter if a single constant is the only thing you are using from that include. eCompile completely ignores any code which is not used in an include when compiling, so you are NOT increasing the size of your compiled scripts by doing this. However, if you frequently find yourself including a file merely to get a couple constant values, and not for any other functions, you should consider splitting your constants into a separate include.
2) Slightly alter the name of the constant in 'secondary' declarations of it. Say, for example, you really, really, really want to avoid having to include client.inc just to get FONT_NORMAL. Do NOT declare a 'FONT_NORMAL' in your script. Instead, declare, [SCRIPTNAME]_FONT_NORMAL. This way, even if you later do decide to include client.inc, your constant will not collide.
I much prefer the first solution, because it avoids unnecessarily declaring constants that have already been declared elsewhere.
If you avoid ever declaring constants with the same name in multiple files, you should not need to worry so much about CWO's B:. Of course, in order for that to be true, you should also use the same principle with function names: Never use the same function names in multiple include files... NEVER! Again, if you have a function that you need, just include the file it's in. Making a separate copy of it just to avoid including a file is avoiding the whole point of includes in the first place. And, again, eCompile is able to optimize these includes - it does NOT include code that it has no calls for. You can verify this by having a validly declared function that nevertheless has some syntax error in it... if that function is not called anywhere at all, eCompile won't complain, because it's not even reading the body of that function.
I would actually go so far as to suggest that it may be very, very difficult, and probably not particularly useful, to try to actually never have includes included from within other includes. As long as you avoid variable, constant and function name collisions, there is no reason at all you can't have all the cross-including you want. Note that unlike compilers for other languages, eCompile will recognize when a file has been included more than once, and will not attempt to do so again.
(There is an except with eCompile for 095, but unless someone asks, I won't clutter up this post with that info!) |
|
 |
|
|
 |
 |
| Author |
Message |
Marilla
Joined: 02 Feb 2006 Posts: 329
|
Posted: Sat Nov 04, 2006 7:36 pm Post subject: |
|
|
Umm... I just realized; this IS the 095 help forum! So, let me explain that caveat to the above!
There are two (maybe three) different ways that eCompile can find your include files, based on how you write the include statement. One is the :package:file format, and the other is simply the normal directory/filename format. For example:
| Code: |
include ":mypackage:myinclude";
include "../pkg/mypackage/myinclude";
|
If you did that in a script/include, eCompile would actually think those are two different files, and it would include them 'both', resulting in name collisions on every single item in that file. Of course, you wouldn't include the file twice in the same file! But you might include it once one way in your script, and once another way in another include.
I said there might be three ways; I'm not sure if eCompile treats the simple 'file name' include method differently or not. That is:
| Code: |
include "myinclude";
|
Anyway, on 095, you should do your best to make sure that each individual include file is always included using the same syntax wherever it may be included, so that eCompile is able to recognize the multiple includes as pointing to the same file.
For instance, if you had an include file /pkg/mypkg/myinc.inc
| Code: |
const MY_COOL_CONST := 1;
|
You could actually put this line in -every single script and include- on your shard, and everything would work fine:
| Code: |
include ":mypkg:myinc";
|
But if you have one include somewhere that does this instead:
| Code: |
include "../pkg/mypkg/myinc";
|
You will get trouble with collisions on the name.
Finally, the current 096 and 097 cores' eCompiles no longer have this problem; they will recognize when you are including the same file, even if you do so by different methods. However, I still recommend always using the same method (and the method I recommend is the :package:file format, now) |
|
 |
|
|
 |
 |
|
 |
 |
|
 |
 |
| Author |
Message |
Marilla
Joined: 02 Feb 2006 Posts: 329
|
Posted: Sun Nov 05, 2006 8:26 pm Post subject: |
|
|
Yup! Put another way, constants which are tested ALONE in a conditional can serve as conditional compilation.
For instance, you could use it to have debug information printed for your combat system, but only when your const TESTING == 1. To publish your code to production, simply change the constant and recompile.
It's important that if you do this, the only thing being tested in your IF() is the constant value... if anything else is involved in the test condition, eCompile can not know the result, and must include all the code.
But as long as that is ALL you are testing in your conditional statements, eCompile will leave anything out when you test for a const that is 0, such as:
| Code: |
use uo;
const TESTING := 0;
program test(who)
var what := 1;
if (TESTING)
what := 2;
endif
print(what);
endprogram
|
With the code above, since TESTING == 0, the whole "if (testing) what:=2; endif might as well not be there at all. Here's the 'lst' contents of compiling the above:
| Code: |
d:\pol\scripts\textcmd\coun\const0.src, Line 5
program test(who)
const TESTING := 0;
0: get arg 'who'
var what := 1;
1: decl local #1
2: 1L
3: :=
4: #
print(what);
5: local #1
6: Func(1,0): print
7: #
8: leave block(2)
9: progend
|
There is absolutely no hint at all of the IF (TESTING) or the what:=2 there.
Now if we just remove the const stuff entirely, as we might otherwise in a 'testing' situation, we might have this code:
| Code: |
use uo;
program test(who)
var what := 1;
print(what);
endprogram
|
This code produces the following lst: Note that it is almost exactly the same as the above!
| Code: |
d:\pol\scripts\textcmd\coun\empty.src, Line 3
program test(who)
use uo;
0: get arg 'who'
var what := 1;
1: decl local #1
2: 1L
3: :=
4: #
print(what);
5: local #1
6: Func(1,0): print
7: #
8: leave block(2)
9: progend
|
It's essentially exactly the same as the code with the TESTING == 0. What if TESTING==1? This is the resulting lst:
| Code: |
d:\pol\scripts\textcmd\coun\const1.src, Line 5
program test(who)
const TESTING := 1;
0: get arg 'who'
var what := 1;
1: decl local #1
2: 1L
3: :=
4: #
what := 2;
5: 2L
6: local1 :=
print(what);
7: local #1
8: Func(1,0): print
9: #
10: leave block(2)
11: progend
|
See the additional code there, where it sets what:=2? But you might notice something missing... What if we had TESTING as a VAR, instead of a CONST? This is the resulting lst:
| Code: |
d:\pol\scripts\textcmd\coun\var1.src, Line 3
var TESTING := 1;
0: decl global #0
1: 1L
2: :=
3: #
d:\pol\scripts\textcmd\coun\var1.src, Line 5
program test(who)
4: get arg 'who'
var what := 1;
5: decl local #1
6: 1L
7: :=
8: #
if (TESTING)
9: global #0
10: if false goto 13
what := 2;
11: 2L
12: local1 :=
print(what);
13: local #1
14: Func(1,0): print
15: #
16: leave block(2)
17: progend
|
Note: Now you can see the IF(TESTING) conditional that it has to keep in the code. Keep in mind all three of the above code are exactly the same, except for the value of 'TESTING', and whether it is a VAR or a CONST.
Clearly, eCompile itself is evaluating IF statements against a CONST, and conditionally compiling based on that. It completely leaves out code that would never run anyway, and it actually even leaves out the conditional itself from the code. If the const evaluates to 'true', it simply outputs the appropriate code into the compiled ecl, as if there was no conditional at all. (That is, exactly like 'conditional compilation' through pre-processor directives would do).
There is one caveat to this, however; You cannot declare a variable within the 'block' of code inside any of those conditionals, on the assumption that eCompile is just removing those blocks. It -IS- removing those blocks, however, it still does not permit the code to compile. An example. Say we adjusted the above example to this:
| Code: |
use uo;
const TESTING := 0;
program test(who)
var what;
if (TESTING)
what := 2;
else
what := 0;
endif
print(what);
endprogram
|
This compiles and runs fine. Since TESTING==0, the whole 'testing' IF is left out, and the code that sets what:=0 is simply run. Here's the lst:
| Code: |
d:\pol\scripts\textcmd\coun\const0.src, Line 5
program test(who)
const TESTING := 0;
0: get arg 'who'
var what;
1: decl local #1
2: #
what := 0;
3: 0L
4: local1 :=
print(what);
5: local #1
6: Func(1,0): print
7: #
8: leave block(2)
9: progend
|
So, you might be tempted to think; Well, if eCompile is not creating a code block for the IF test, can I just declare the WHAT var within those blocks, like so?
| Code: |
use uo;
const TESTING := 0;
program test(who)
if (TESTING)
var what := 2;
else
var what := 0;
endif
print(what);
endprogram
|
This looks like it won't work, and you are right. It won't work:
| Code: | | Variable what has not been declared on line 11. |
Even though eCompile does collapse that block, it apparently does not do that until AFTER it has checked to be sure all the variables are in proper scope in the blocks and such. This makes sense, since eCompile probably has to examine a lot of the structure of a function before it can be sure that conditionals testing a const are ONLY testing a const, and not somewhere down the line testing a variable or function return value, also. So, the above has to be written as originally. |
|
 |
|
|
|