Initializer element is not a compile time constant ошибка

When compiling this code, I get the error «initializer element is not a compile-time constant». Can anyone explain why?

#import "PreferencesController.h"

@implementation PreferencesController

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}


NSImage* imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];//error here

jscs's user avatar

jscs

63.6k13 gold badges150 silver badges194 bronze badges

asked May 26, 2011 at 18:07

Nick's user avatar

When you define a variable outside the scope of a function, that variable’s value is actually written into your executable file. This means you can only use a constant value. Since you don’t know everything about the runtime environment at compile time (which classes are available, what is their structure, etc.), you cannot create objective c objects until runtime, with the exception of constant strings, which are given a specific structure and guaranteed to stay that way. What you should do is initialize the variable to nil and use +initialize to create your image. initialize is a class method which will be called before any other method is called on your class.

Example:

NSImage *imageSegment = nil;
+ (void)initialize {
    if(!imageSegment)
        imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];
}
- (id)init {
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

answered May 26, 2011 at 18:22

ughoavgfhw's user avatar

ughoavgfhwughoavgfhw

39.7k6 gold badges101 silver badges123 bronze badges

6

A global variable has to be initialized to a constant value, like 4 or 0.0 or @"constant string" or nil. A object constructor, such as init, does not return a constant value.

If you want to have a global variable, you should initialize it to nil and then return it using a class method:

NSImage *segment = nil;

+ (NSImage *)imageSegment
{
    if (segment == nil) segment = [[NSImage alloc] initWithContentsOfFile:@"/user/asd.jpg"];
    return segment;
}

answered May 26, 2011 at 18:14

mipadi's user avatar

mipadimipadi

396k89 gold badges523 silver badges479 bronze badges

2

Because you are asking the compiler to initialize a static variable with code that is inherently dynamic.

answered May 26, 2011 at 18:14

bbum's user avatar

bbumbbum

162k23 gold badges271 silver badges359 bronze badges

The reason is that your are defining your imageSegment outside of a function in your source code (static variable).

In such cases, the initialization cannot include execution of code, like calling a function or allocation a class. Initializer must be a constant whose value is known at compile time.

You can then initialize your static variable inside of your init method (if you postpone its declaration to init).

answered May 26, 2011 at 18:15

sergio's user avatar

sergiosergio

68.8k11 gold badges102 silver badges122 bronze badges

2

You can certainly #define a macro as shown below. The compiler will replace «IMAGE_SEGMENT» with its value before compilation. While you will achieve defining a global lookup for your array, it is not the same as a global variable. When the macro is expanded, it works just like inline code and so a new image is created each time. So if you are careful in where you use the macro, then you would have effectively achieved creating a global variable.

#define IMAGE_SEGMENT [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];

Then use it where you need it as shown below. Each time the below code is executed, a new object is created with a new memory pointer.

imageSegment = IMAGE_SEGMENT

answered Jun 2, 2015 at 15:38

Kris Subramanian's user avatar

You can use the static singleton approach with dispatch_once:

#define STATIC_VAR(type, code) ^type() { 
    static type object; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
        object = code; 
    }); 
    return object; 
};

#define let __auto_type const

let imageSegment = STATIC_VAR(UIImage*, [[UIImage alloc] initWithContentsOfFile:@"image.jpg"]);
let imageRect = STATIC_VAR(CGRect, CGRectMake(0, 0, 100, 100));

// How to use:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.imageView.image = imageSegment();
    self.imageView.frame = imageRect();
}

It is thread safe, works lazily with any type and makes only a single instance.

answered Aug 12, 2021 at 10:10

iUrii's user avatar

iUriiiUrii

10.9k1 gold badge31 silver badges44 bronze badges

I got this error while practicing C language, my code that I was trying to run was this

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    char *name;
    int age;
} person;

person *p = (person *)malloc(sizeof(person));

and I realized while reading answers, that in C, I should have main function, which I forgot to use, so put the person code in main function, thus removing the error as follows

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    char *name;
    int age;
} person;

int main()
{

    person *p = (person *)malloc(sizeof(person));
    return 0;
}

answered Mar 18, 2022 at 7:48

Akshay Vijay Jain's user avatar

I have been looking for answers but could not find anything to make this code run. I get av[1] highlighted by the compiler in the main function when declaring:

static char const *str = av[1];

Here is the code I tried to run with gcc:

#include <stdio.h>
#include <stdlib.h>

char    *ft_strjoin(char const *s1, char const *s2);

void    fct(char **av)
{
    static char const *str = av[1];
    str = ft_strjoin(av[1], av[1]);
    printf("%sn", str);
}

int main(int ac, char **av)
{
    fct(&av[1]);
    fct(&av[1]);
    fct(&av[1]);
    fct(&av[1]);
    fct(&av[1]);
    fct(&av[1]);
}

I found this interesting but I still don’t get it and don’t know how to run this code.

Sourav Ghosh's user avatar

Sourav Ghosh

133k16 gold badges183 silver badges261 bronze badges

asked Dec 24, 2015 at 9:09

ziKmouT's user avatar

3

Quoting C11, §6.7.9, Initialization

All the expressions in an initializer for an object that has static or thread storage duration
shall be constant expressions or string literals.

In your code,

static char const *str = av[1];

av[1] is not a compile time constant value (i.e., not a constant expression). Hence the error.

You need to remove static from str to avoid the issue.

fuz's user avatar

fuz

87.8k24 gold badges196 silver badges349 bronze badges

answered Dec 24, 2015 at 9:20

Sourav Ghosh's user avatar

Sourav GhoshSourav Ghosh

133k16 gold badges183 silver badges261 bronze badges

static variables need to be initialised with a compile time constants (constant literals). av[1] will be calculated at runtime and that’s why you are getting the error message.

answered Dec 24, 2015 at 9:15

haccks's user avatar

hacckshaccks

104k25 gold badges175 silver badges264 bronze badges

You could simulate that behaviour by writing:

static const char *str;
static bool already;
if ( !already )
{
    str = av[1];
    ++already;
}

However this would be redundant compared to the solution of:

const char *str;

because you immediately overwrite that value anyway with the return value of your function.

(Also you pass the same argument in every call, so even if you used str, it still doesn’t need to be static).

answered Dec 24, 2015 at 9:34

M.M's user avatar

M.MM.M

138k21 gold badges204 silver badges357 bronze badges

Initializer element is not constant define error might occur while using GCC 7.4.0 due to its lack of support for the const qualifier. Therefore, assigning incorrectly defined or improperly placed constants to the static variables results as this error.Initializer element is not constant

But you don’t need to worry even if you can’t figure out the problem in your code all alone because this article will assist you in every aspect that relates to the same error. Read the entire post to discover your difficult-to-locate mistakes and correct them to eliminate the error.

Contents

  • Initializer Element Is Not Constant: What Are the Causes?
    • – Const and GCC 7.4.0
    • – You Have an Unclear Concept of Constants
    • – Your Constants Aren’t Placed Inside the Main Function
    • – You Haven’t Initialized a Static Variable With a Constant
  • Solutions for the Initializer Element Is Not Constant Error
    • – Using #define Will Make Things Work
    • – Update To GCC 8.1 or a Later Version
    • – Assign Correct Values To the Constants
    • – Add the Difficult-to-evaluate Code Inside a Function
    • – Add the Constants Inside the Main Function
  • Conclusion
  • References

Initializer Element Is Not Constant: What Are the Causes?

The cause of the initializer element is not constant error is that the program not initializing the static variable with a constant. Other problems include using the const qualifier with GCC 7.4.0 compiler, a weak concept of constants, or placing the constants outside the main() function.

– Const and GCC 7.4.0

If you are using GCC 7.4.0 and you try to create constants by using the const qualifier, the given error will show up on your screen. You must know that the const-qualified objects are not considered constants by GCC 7.4.0.

For example, you have created a constant of int data type. Its value equals 50. But as soon as you try to use it to initialize an object with static storage duration, you get an error stating that the initializer element is not constant define.

Here is the erroneous code snippet that’ll throw an error when compiled using GCC 7.4.0:

const int H = 50;

static int R = H;

– You Have an Unclear Concept of Constants

If you aren’t clear about the valid values that must be assigned to the constants, you might receive the same error at some point in your program. Assigning invalid values to the constants isn’t a good practice. Such values aren’t acceptable and can hinder the creation of constants.

For example, you are trying to make a large object a constant. It won’t be possible to do it. Consequently, you’ll get the stated error when you use the same constant to initialize a static storage duration.Causes of the initializer element is not constant error

– Your Constants Aren’t Placed Inside the Main Function

The constants placed outside your main function and assigned to your static variables can lead to the initializer element is not constant static error. It means that it’s not only about the constant values, but the position of the constants is important too.

Moreover, the compiler finds it difficult to evaluate the constant values and assign them to another variable. Thus, if you try to assign a variable to another at compile-time, you’ll see the initializer element is not constant struct on your screen.

Imagine that you have defined two constants and assigned their sum to a static variable. But an error pops up when you try to compile the code.

Here is the code block that might result in the given error:

const int NUM1 = 40;

const int NUM2 = 80;

static int RES = NUM1 + NUM2;

– You Haven’t Initialized a Static Variable With a Constant

Initializing a static storage duration with a constant expression or with an aggregate initializer containing a constant expression is crucial. If you do it any other way, the error under consideration will pop up. Thus, you can not assign a non-constant value to a static variable.

Think about it this way. You have an int variable. Now, you want to create a new static variable and assign the same number to it. In this case, you’ll receive the initializer element is not a compile-time constant error.

The following code snippet depicts the above scenario to help you out:

int NUM = 700;

static int LENGTH = NUM;

Solutions for the Initializer Element Is Not Constant Error

You can solve the initializer element is not constant calloc error by creating the constants perfectly and initializing the static variables with the constants. You can create perfect constants by using #define instead of the const qualifier with GCC 7.4.0 or updating to GCC 8.1.

– Using #define Will Make Things Work

As in GCC 7.4.0, the const qualifier doesn’t help in creating constants and can cause the initializer element is not constant malloc. Thus, you should use #define to create named constants. This way, you won’t even need to position the constants inside the main function.Solutions for initializer element is not constant error

So, all that you’ll need to do is to opt for the method that uses #define to create constants. Consequently, the constants will be created perfectly, and the reason for the given error will be vanished leading to the removal of the given error.

Look below to know how to use #define.

– Update To GCC 8.1 or a Later Version

The const qualifier is supported in the GCC 8.1 and later versions. Hence, if you update your compiler, you’ll see the stated error go away. Also, you’ll not need to make changes to your code. You can get the update by changing your tool chain to gnu-tools-for-stm32.9-2020-q2-update.

The given tool chain uses GCC v9.3.1, which is sufficient to compile a code block similar to the one shared below.

const int H = 50;

static int R = H;

– Assign Correct Values To the Constants

The constants can take up literals, such as strings, characters, integers, float values, and enumerations. Besides this, a constant expression must evaluate to a null pointer constant, an arithmetic constant expression, or an address constant. Once you fix the constant value, the error should go away.

Also, note that a constant expression can evaluate to an address constant for an object type minus or plus an integer constant expression.Solutions for initializer element is not constant

– Add the Difficult-to-evaluate Code Inside a Function

You should add the difficult-to-evaluate code inside a function to resolve the initializer element is not constant fopen error. This way, the compiler won’t get confused, and eventually, you’ll not get the said error.

Here is the code that will work just the way you want.

#include<stdio.h>

int func1(){

const int NUM1 = 40;

const int NUM2 = 80;

static int RES = NUM1 + NUM2;

}

– Add the Constants Inside the Main Function

Adding the constants inside the main function will help resolve the initializer element is not constant array error. The main function is considered the starting point of your program. So, it would be best to include the constants inside the same as an attempt to confirm their creation.

The following block of code creates a constant and a static variable inside the main function to avoid all the conflicts of the compiler and the code.

int main(){

const int AREA = 50;

static int VAL = AREA;

}

Conclusion

Hopefully, The initializer element is not constant error is no more frustrating because you have learned about the various issues that can lead to faulty constants. Plus, you have found out the ways to create the constants that’ll help in the initialization of the static variables.

Please read the list of crucial points from this post to clarify your remaining doubts:

  • You can use #define to create the constants while running GCC 7.4.0 to resolve the error immediately.
  • If you want to use the const qualifier, then you’ll need to update your compiler GCC 8.1 or a newer version and get rid of the error.
  • Ensure to provide only literals to the constants, which include strings, integers, characters, float values, and enumerations.
  • Add the code that is difficult to evaluate inside a function to satisfy the compiler and stop it from showing you the given error.
  • You should add the constants inside the main() function to confirm their creation and kick away the error in the title.

So, the better constants you create and the better you understand the relationship between the constants and the static variables, the more efficient you’ll be at solving the same error.

References

  • https://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w
  • https://cboard.cprogramming.com/c-programming/176605-initializer-element-not-constant.html
  • https://stackoverflow.com/questions/12750796/initializer-element-is-not-constant-in-c?noredirect=1&lq=1
  • Author
  • Recent Posts

Position is Everything

Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team

Position is Everything

You have the right idea behind how the code works, it’s just your English to C needs some practice (understandably).

int main(void);

This is, as its name suggests, the «main» method. Essentially, when you say to run the program, it looks for main(void) and goes from there. Therefore, all your other code should be inside this function, Which will take care of error number one.

int main(void)
{
    // code goes here
}

Next up: The do-while. First, after the closing ) in the while there should be a ;. Next, !> and !< aren’t recognized by C. Your options are ==, !=, > and <. So instead of saying «while n isn’t greater than 0 and isn’t less than 23», instead try «while n is outside the boundries (of 0 and 23)».

Let me know if you could use more guidance, particularly on the second part. You’re doing well so far!

При компиляции этого кода я получаю ошибку «элемент инициализации не является константой времени компиляции». Может кто-нибудь объяснить, почему?

#import "PreferencesController.h"

@implementation PreferencesController

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}


NSImage* imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];//error here

4b9b3361

Ответ 1

Когда вы определяете переменную вне области действия функции, это значение переменной фактически записывается в ваш исполняемый файл. Это означает, что вы можете использовать только постоянное значение. Поскольку вы не знаете все о среде выполнения во время компиляции (какие классы доступны, какова их структура и т.д.), Вы не можете создавать объектные объекты c до выполнения, за исключением постоянных строк, которым заданы конкретные структуры и гарантированно останется таким образом. Что вам нужно сделать, это инициализировать переменную до нуля и использовать +initialize для создания вашего изображения. initialize — это метод класса, который будет вызываться до вызова любого другого метода в ваш класс.

Пример:

NSImage *imageSegment = nil;
+ (void)initialize {
    if(!imageSegment)
        imageSegment = [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];
}
- (id)init {
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

Ответ 2

Глобальная переменная должна быть инициализирована с постоянным значением, например 4 или 0.0 или @"constant string" или nil. Конструктор объекта, такой как init, не возвращает постоянное значение.

Если вы хотите иметь глобальную переменную, вы должны инициализировать ее до nil, а затем вернуть ее с помощью метода класса:

NSImage *segment = nil;

+ (NSImage *)imageSegment
{
    if (segment == nil) segment = [[NSImage alloc] initWithContentsOfFile:@"/user/asd.jpg"];
    return segment;
}

Ответ 3

Потому что вы просите компилятор инициализировать статическую переменную с кодом, который по своей сути является динамическим.

Ответ 4

Причина в том, что вы определяете свой imageSegment вне функции в исходном коде (статическая переменная).

В таких случаях инициализация не может включать выполнение кода, например вызов функции или распределение класса. Инициализатор должен быть константой, значение которой известно во время компиляции.

Затем вы можете инициализировать свою статическую переменную внутри вашего метода init (если вы отложите ее объявление до init).

Ответ 5

Вы можете указать #define макрос, как показано ниже. Компилятор заменит «IMAGE_SEGMENT» своим значением перед компиляцией. Хотя вы достигнете определения глобального поиска для вашего массива, это не то же самое, что глобальная переменная. Когда макрос расширяется, он работает так же, как встроенный код, и каждый раз создается новое изображение. Поэтому, если вы будете осторожны в том, где используете макрос, вы бы эффективно достигли создания глобальной переменной.

#define IMAGE_SEGMENT [[NSImage alloc] initWithContentsOfFile:@"/User/asd.jpg"];

Затем используйте его там, где вам это нужно, как показано ниже. Каждый раз, когда выполняется следующий код, создается новый объект с новым указателем памяти.

imageSegment = IMAGE_SEGMENT

Понравилась статья? Поделить с друзьями:
  • Inithelperdll в nshhttp dll код ошибки 10107
  • Ingenico iwl250 ошибка alert irruption
  • Ingenico ipp320 ошибка связи нет подключения
  • Info error grease cent lubr ошибка ман тга
  • Info engine fault ошибка пежо 308