-3

I'm trying to assign a value to my #define using a method that gets said value from a file.

I'm able to get the value from the file and return it to the main method. The define is able to call it and initialize it, but when another method uses said define, I get this error "initializer element is not constant"

I tried to set the method as const int, but I didn’t have any success. What can I do to fix this?

Code Example:

#define VALUE getValue()

int getValueFromFile(){
    File *fp;
    int value;
    if((fp = fopen("configFile.txt","rt")) != NULL){
            fscanf(fp,"value=%d\n",&value);
            fclose(fp);
            return value;
    }else{
            return -1;
}

int getValue(){
    int value;
    if((value=getValueFromFile()) != -1){
          return value;
    }else{
          return 10;
}

Then when I try to use it like

static unsigned long int testValue = (unsigned long int) VALUE;

I get the error "initializer element is not constant"


Ok, so the #define is no good. I'm trying to use a global variable, but the error now changed to "error: variably modified ---- at file scope" The global variable are not static.

What should I do?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fabzheimer
  • 45
  • 5
  • 3
    Can you post some code example? – KamilCuk May 24 '18 at 13:05
  • 1
    We can't help to debug code without any code to debug. – Lundin May 24 '18 at 13:07
  • 1
    You should show some code to illustrate the problem — an MCVE ([MCVE]). However, you can only use a function call in the initializer for an automatic variable, not for variables at file scope or `static` inside a function. – Jonathan Leffler May 24 '18 at 13:07
  • If said value is obtained via a function call, it's not a (compile-time) constant value and you can't use it where a compile-time constant is required. You'll need a different solution. – Petr Skocik May 24 '18 at 13:09
  • Please show your code instead of describing it. – Jabberwocky May 24 '18 at 13:11
  • 1
    It took a bit of time but here it is some code example of my problem – Fabzheimer May 24 '18 at 13:13
  • 1
    After your edit the question is clear. In C you cannot initialize a global variable by calling a function. In your case `static unsigned long int testValue = (unsigned long int) VALUE;` is the same as `static unsigned long int testValue = (unsigned long int) getValue();` – Jabberwocky May 24 '18 at 13:34
  • Please condense your code into a [mcve]. At the moment, it's completely unclear as to the scope of your `testValue` declaration. (And there's no need for file I/O in your demo code). – Toby Speight May 24 '18 at 14:51
  • Related: *[Can the C preprocessor perform integer arithmetic?](https://stackoverflow.com/questions/1560357/)* – Peter Mortensen Aug 15 '23 at 13:10
  • Related: *[Preprocessor functions evaluated at compile time in C](https://stackoverflow.com/questions/3791264/preprocessor-functions-evaluated-at-compile-time-in-c)* – Peter Mortensen Aug 15 '23 at 13:14

2 Answers2

4

There may be a misunderstanding of what "#define" is. It is a preprocessor directive, meaning that before the source code is compiled, it's modified by a preprocessor, who then hands it off to the compiler.

Much like #include almost literally copies and pastes text into that location of a source file, #define has the preprocessor mark a label as being equal to some literal, macro, etc., and simply replaces all instances of that label with the given value.

More on preprocessor directives.

In your situation, preprocessor values certainly cannot be 'set' at runtime. You may want a global variable that isn't const to be set and used throughout.

Just keep in mind that it's bad form to rely on those (in most cases), and consider how much work would be needed to avoid it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sean Monroe
  • 173
  • 5
  • I'm trying to use global variable but now the error is "error: variably modified 'array' at file scope – Fabzheimer May 24 '18 at 14:10
  • @Fabzheimer At this point the question is deviating from "setting a define value at runtime". You may want to ask a new question with code that reproduces the error, after having done enough research and effort to fix the new error. – Sean Monroe May 24 '18 at 15:49
  • I agree, but since they voted my question down i can't ask another question for a week – Fabzheimer May 24 '18 at 15:55
  • @Fabzheimer I don't like to do this but searching that error has returned plenty of results, including [this one.](https://stackoverflow.com/questions/1712592/variably-modified-array-at-file-scope) Do a bit more research, and you'll see there's nothing new under the sun. – Sean Monroe May 24 '18 at 15:57
  • Yep, i found that too. The problem is different for me because the error i'm facing is caused by a struct and no matter how i define the global variable it keeps giving me that error :/ – Fabzheimer May 24 '18 at 16:00
  • @Fabzheimer I'm sorry, but without code to put this new error in context, there can't be anymore help here. It sounds like you're trying to declare an array using a variable (which you can't do), but I can't be sure and I'm unwilling to carry this convo on in a comment section. – Sean Monroe May 24 '18 at 16:08
0

In C, to initialize an object with a value that is computed rather than constant, you can set it in the main routine (or a routine called from the main routine when it starts):

static unsigned long testValue;

int main(void)
{
    testValue = getValue();
    …
}

In C, there is no way to initialize a static object with a computed value, other than simple “constant expressions.” If you want to initialize an object with a value that can be computed at compile-time (for example, sin(.01)—all the information needed to determine the value is available at run-time, but it requires calling a function), this can be done by running a program at compile-time that computes the value and writes new source code that is incorporated into the program before compilation. If you want to initialize an object with a value that cannot be computed at compile-time because it needs information only available at run-time, then you must use an assignment in the running program, not compile-time initialization.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312