Of course I know header file. But my problem is that: I have a lot of C files, who share one Header file, and I made a library. But when I use the library in different projects, I need to modify the parameters, which are defined as MACROs. So I want to determine these constants' value at linking time. If they are defined as external code MAX; external code MIN_VALUE; Then the source code grows larger, and even worse, some important functions are no longer reentrant-able, because no more registers can be used to pass function paramters. My library is an operation system based on 51. So you know that reentrant function are import. I have tries for several months but still fail. It's really a chanllenging problem, and it's every useful for building a library whose parameters can be configured in an ASM file. Can any one have a solution?
If the value of MAX changes for every project, I'd most likely use a different header file with MAX for every project. If it's a big header with most stuff common to all projects, and you just want to change MAX, then you can pull MAX out into its own header (per project, in some project-specific directory) and have the one big global header #include the per-project version (likely in some sort of global code directory). The library customization parameters would be isolated in their own header, separate from any other. That makes it easier for the user to tweak, too, compared with trying to document something like "go to lines 135-147 of header.h and edit the variables there". Another alternative is to define the value for MAX externally, at compile time (on the command line or the DEFINE box in UV2), and not in a header at all. Every project will have its own project/make file, and those can specify different values for max. The one big header doesn't define MAX at all. In that case, I'd recommend some defensive preprocessor code along the lines of:
#if !defined(MAX) #error Must define MAX before compiling header.h #endif
/*----------------------------------------*/ C51 problem: Incomplete optimization. Please see the following code. 1. Compile this source file, and save the .lst file 2. comment off "BAD_CODE", and then compare the .lst file with the previous one. You will find that when compiled with BAD_CODE, the statement i<MAX is very lengthy, and more memory is used, even worse, the function is no longer reentrant. Actually, as we can see from the .lst file, this is due to the incomplete optimization of C51, who generated redundant code. If this problem is resolved, it can be very useful, because the value of a constant can be determined at linking time. For example, the parameter of a library can be configured by an ASM file, instead of giving the source code to customer and ask him to compile again. --------------------------------------------------------------*/ //comment of this macro to compare the result. #define BAD_CODE #ifdef BAD_CODE //this is defined in another source file extern unsigned char MAX[]; #define MAX (unsigned char)MAX #else //define MAX as constant, and you will find //smaller code size, and better register usage #define MAX 3 #endif //when compiled by BAD_CODE, x will be saved in data_group, //otherwise, x is in R1-R3,and this function is reentrant-able void test(unsigned char i, unsigned char *x) { if(i>MAX) *x = 34; else *x = 56; } void main() { test(1,1); }
and I made a library. But when I use the library in different projects, I need to modify the parameters, which are defined as MACROs. Macros are processed by the COMPILER, and functions in a library are "precompiled". Thus if you change a macro, you must compile again. I build my libraries for every project in the .bat file that generates the code. Erik