-3

I have a file, file1.c, where I would like to define some constants if some requirements are met, to be used in an other file, file3.c.

file1.c:

#include "header.h"

int set_constants(void) {

#ifdef EXAMPLE_MACRO
  int fd, status, size;

  fd = open(EXAMPLE_DRIVER, RD_ONLY);

  ioctl(fd, EXAMPLE_IOCTL_CHECK_SIZE, &size);

  if (size == SIZE_CONDITION) {
    /* Here i would like to define the constants 
       A, B, and C. */
  } else {
    /* Here I would like to define the constants
       A, B, and C to something else than above. */
  }
  return 0;

#endif

/* If EXAMPLE_MACRO is not defined, I would like to set
   A, B and C to something else. */
  return 0;

The function, set_constants(), would be called from an init function in file2.c, which makes a call to a function in file3.c that uses the constant A:

#include "header.h"

void file2_init(void) {
  set_constants();

  file3_function();
}

In file3.c, I would like to create a global array with A elements:

#include "header.h"

uint8_t array[A];

void file3_function(void) 
{
  /* Do something with array */
}

I understand that A, B and C can not be defined as macros, since the variable size is not known when the macros are processed by the pre-processor. Would such constants even be possible to create (using the language C)?

I've tried to define A, B, and C as global integer variables (I know they are not constant, but it is my only idea so far) in file1.c, and declared them like this in a header file header.h:

#ifndef _MY_HEADER_H_
#define _MY_HEADER_H

extern int A;
extern int B;
extern int C;

void set_constants(void);
void file3_function(void);

#endif _MY_HEADER_H_

But then I get the error:

error: variably modified 'array' at file scope

array[A] needs to be at global scope, my question is, how do i declare and define A, B, and C such that they are visible to file3.c, and do not rise the error above?

I've also tried to make A, B, and C to const int, like so;

#include "header.h" 
int set_constants(void) {

#ifdef EXAMPLE_MACRO
  int fd, status, size;

  fd = open(EXAMPLE_DRIVER, RD_ONLY);

  ioctl(fd, EXAMPLE_IOCTL_CHECK_SIZE, &size);

  if (size == SIZE_CONDITION) {

    const int A = 1;
    const int B = 1;
    const int C = 1;

  } else {

    const int A = 2;
    const int B = 2;
    const int C = 2;
  }
  return 0;

#endif

  const int A = 3;
  const int B = 3;
  const int C = 3;

  return 0;

and declared A, B, and C to extern const int in header.h:

#ifndef _MY_HEADER_H_
#define _MY_HEADER_H

extern const int A;
extern const int B;
extern const int C;

void set_constants(void);
void file3_function(void);

#endif _MY_HEADER_H_

But then I get the compile error:

error: declaration of 'A' shadows a global declaration [-Werror=shadow] const int A = 1;
In file included from file1.c: header.h: error: shadowed declaration is here [-Werror=shadow] extern const int A;

LukesDiner
  • 145
  • 8
  • 1
    What is the problem you're trying to solve? Does it cause any problems to define them at compile time? – klutt Jan 28 '20 at 11:39
  • @pikopiko As you may have read in other comments, you need to clarify your question. Rephrasing the information that is already present in the question does not help. (as you did in the comment just now) What is the original problem you want to solve? Do you need `array[A]` to be at global scope? Can you move it into `file3_function`? – Bodo Jan 28 '20 at 12:40
  • @pikopiko That's not *clarifying*. It's just *repeating*. I assume you have a reason to do what you're trying to do? – klutt Jan 28 '20 at 12:40
  • @bodo I need array[A] to be at global scope and I can not move it into file3_function. – LukesDiner Jan 28 '20 at 12:43
  • @pikopiko Please [edit] your question to add clarification. Explain why `array[A]` must be global. If we knew your original problem we might be able to propose alternative solutions. – Bodo Jan 28 '20 at 12:47
  • @pikopiko You still didn't make clear **why** (you think that) `array[A]` must be global. You cannot have a global variable length array, so you cannot avoid the error `variably modified 'array' at file scope` (But you could use `malloc` or similar.) If you declare `const int A = 1;` inside a block, this is a new variable which shadows the global variable. If you declare the variables as `const` at global scope you can initialize the value at the same place, you cannot assign a value from inside a function. – Bodo Jan 28 '20 at 13:49
  • @klutt I do not know what the variable *size* is at compile time, it is read out at runtime. Depending on what value *size* is at runtime, i would like to set different values for A, B, and C. Thanks! – LukesDiner Jan 28 '20 at 13:51
  • @pikopiko You still have not mentioned what the *actual* problem is... – klutt Jan 28 '20 at 14:03
  • To elaborate a little bit. I have no clue (that's a lie, I have some educated guesses) what you're trying to achieve, but everything points in the direction that you're trying to solve whatever problem you have in the wrong way. Imagine someone posting a question with the "problem" that the fuse blows everytime you throw the hair dryer in the bath tub. I could "solve" the problem bu replacing the fuse with a thick nail. But chances are pretty high that whatever the real problem is, the solution is not to throw the hair dryer in the bath tub. – klutt Jan 28 '20 at 14:11

1 Answers1

2

For a globally-scoped uint8_t array[A]; to work, A must be known at compile time. The initialized memory is literally found in the executable objects file.[1] A such, you will not be able to use uint8_t array[A];; you will need to use dynamic memory allocation (e.g. malloc).


  1. If it's initialized to all zero bytes, it's placed in a memory page that allocated at run-time, but the fact that it's all zeroes must still be known at compile-time in order to know to take this approach.
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 2
    Since the array is not explicitly initialized with values, but implicitly initialized with zeroes, the memory is not found literally in the executable objects file, but space on the `bss` is reserved. – Ctx Jan 28 '20 at 12:24