More on: Help me: how to determine constant value at link time?

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?

Parents
  • 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
    

    just that so when you forget about MAX when setting up the next project, you'll get some sort of hopefully meaningful reminder rather than a syntax error.

    If you really do want the value to be specified as some value in an object module at link time, then I'd think it nearly inevitable that the compiler will generate code to access the address at which the variable lives, which is generally going to be larger code than including the constant value as an immediate operand in the instruction.

    The linker can't really patch the code up, because the code generator has already generated code to do the variable accesses, and it's a bit late for the linker to go back, find all the references to a memory location, and rewrite the instructions so that they use immediate operands that correspond to the value at some offset in some other file.

    One kludge I've seen used to do things like find the end of the actual program code is to define some special segments that locate right after the end of code (for example), and then use that value or the address of a variable defined in that bogus segment to get a link-time result. In this case, you'd have to define the bogus segments for all your parameters, and tell the linker where to put them so that the addresses matched the values you wanted for the parameters. With more than a parameter or two, this technique can easily break down. (What if you need two values of 10, for example? Might not be able to put two segments at the same place....)

Reply
  • 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
    

    just that so when you forget about MAX when setting up the next project, you'll get some sort of hopefully meaningful reminder rather than a syntax error.

    If you really do want the value to be specified as some value in an object module at link time, then I'd think it nearly inevitable that the compiler will generate code to access the address at which the variable lives, which is generally going to be larger code than including the constant value as an immediate operand in the instruction.

    The linker can't really patch the code up, because the code generator has already generated code to do the variable accesses, and it's a bit late for the linker to go back, find all the references to a memory location, and rewrite the instructions so that they use immediate operands that correspond to the value at some offset in some other file.

    One kludge I've seen used to do things like find the end of the actual program code is to define some special segments that locate right after the end of code (for example), and then use that value or the address of a variable defined in that bogus segment to get a link-time result. In this case, you'd have to define the bogus segments for all your parameters, and tell the linker where to put them so that the addresses matched the values you wanted for the parameters. With more than a parameter or two, this technique can easily break down. (What if you need two values of 10, for example? Might not be able to put two segments at the same place....)

Children
More questions in this forum