Error c2131 expression did not evaluate to a constant

// foo.hpp file class foo { public: static const int nmConst; int arr[nmConst]; // line 7 }; // foo.cpp file const int foo::nmConst= 5; Compiler VC 2015 return
// foo.hpp file 
class foo 
    { 
    public: 
      static const int nmConst; 
      int arr[nmConst]; // line 7 
    };  
// foo.cpp file 
    const int foo::nmConst= 5; 

Compiler VC 2015 return error:

1>foo.h(7): error C2131: expression did not evaluate to a constant
1> 1>foo.h(7): failure was caused by non-constant arguments or
reference to a non-constant symbol 1> 1>foo.h(7): note: see usage of
‘nmConst’

Why? nmConst is static constant with value defined in *.cpp file.

Raktim Biswas's user avatar

asked Nov 10, 2015 at 7:54

user3437441's user avatar

0

It’s possible to use static const int member as an array size, but you’ll have to define this member within class in your .hpp file like so:

class foo
{
public:

    static const int nmConst = 10;
    int arr[nmConst];

};

This will work.

P.S. About the logic behind it, I believe compiler wants to know size of the array member as soon as it encounters class declaration. If you leave static const int member undefined within the class, compiler will understand that you’re trying to define variable-length array and report an error (it won’t wait to see if you actually defined nmconst someplace).

answered Nov 10, 2015 at 8:07

dbajgoric's user avatar

dbajgoricdbajgoric

1,44711 silver badges17 bronze badges

0

Permalink

Cannot retrieve contributors at this time

description title ms.date f1_keywords helpviewer_keywords

Learn more about: Compiler Error C2131

Compiler Error C2131

02/28/2019

C2131

C2131

Compiler Error C2131

expression did not evaluate to a constant

An expression declared as const or constexpr didn’t evaluate to a constant at compile time. The compiler must be able to determine the value of the expression at the point it’s used.

Example

This example shows a way to cause error C2131, and how to fix it.

// c2131.cpp
// compile by using: cl /EHsc /W4 /c c2131.cpp

struct test
{
    static const int array_size; // To fix, init array_size here.
    int size_array[array_size];  // C2131
};

const int test::array_size = 42;
c2131.cpp
c2131.cpp(7): error C2131: expression did not evaluate to a constant
c2131.cpp(7): note: failure was caused by non-constant arguments or reference to a non-constant symbol
c2131.cpp(7): note: see usage of 'array_size'

See also

const
constexpr

Ошибки компилятора с C2100 по C2199

В статьях в этом разделе документации объясняется подмножество сообщений об ошибках, создаваемых компилятором.

Компиляторы и средства сборки Visual Studio могут сообщать о различных типах ошибок и предупреждений. После обнаружения ошибки или предупреждения средства сборки могут делать предположения о намерении кода и пытаться продолжить работу, чтобы можно было сообщать о дополнительных проблемах одновременно. Если средства делают неверное предположение, последующие ошибки или предупреждения не могут применяться к проекту. При устранении проблем в проекте всегда начинайте с первой зарегистрированной ошибки (или предупреждения) и выполняйте повторную сборку как можно чаще. Одно исправление может привести к возникновению многих последующих ошибок.

Чтобы получить справку о конкретном диагностическом сообщении в Visual Studio, выберите его в окне вывода и нажмите клавишу F1 . Visual Studio открывает страницу документации для этой ошибки, если она существует. Вы также можете использовать средство поиска в верхней части страницы, чтобы найти статьи о конкретных ошибках или предупреждениях. Кроме того, просмотрите список ошибок и предупреждений по инструменту и введите оглавление на этой странице.

Не все ошибки или предупреждения Visual Studio описаны. Во многих случаях диагностическое сообщение предоставляет все доступные сведения. Если вы приземлились на этой странице при использовании F1 и считаете, что сообщение об ошибке или предупреждении требует дополнительного объяснения, сообщите нам об этом. Кнопки обратной связи на этой странице можно использовать для создания проблемы с документацией на сайте GitHub. Если вы считаете, что ошибка или предупреждение неправы или обнаружена другая проблема с набором инструментов, сообщите о проблеме с продуктом на сайте Сообщество разработчиков. Вы также можете отправить отзыв и ввести ошибки в интегрированной среде разработки. В Visual Studio перейдите в строку меню и выберите «Отправить > отзыв справки>» или отправьте предложение с помощью отправки > отзывов > справки.

Вы можете найти дополнительную помощь по ошибкам и предупреждениям на форумах Microsoft Learn Q&A . Или найдите номер ошибки или предупреждения на сайте Сообщество разработчиков Visual Studio C++. Вы также можете выполнить поиск решений в Stack Overflow .

Ссылки на дополнительные справочные материалы и ресурсы сообщества см. в справке и сообществе Visual C++.

Источник

Error c2131 выражение не определяется константой

Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.3.2016

Репутация: нет
Всего: нет

Сгенерировать и вывести на экран массив с 10 рандомных чисел от -50 до 50. Положительные элементы массива перенести в другой массив №1, а отрицательные в другой №2.
#include «stdafx.h»
#include
#include
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
<
int *mas, n;
cout > n;
mas = new int[n];
int positiv = 0, negativ = 0;
for (int j = 0; j 0)
positiv++;

>
int *mas_p = new int[positiv];
int *mas_n = new int[negativ];

stargame
Дата 16.3.2016, 20:18 (ссылка) | (нет голосов) Загрузка .
rudolfninja
Дата 16.3.2016, 20:57 (ссылка) | (нет голосов) Загрузка .

Опытный

Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6

Вы код забыли полностью дописать.
Если вы этот код писали самостоятельно, то, в принципе, у вас не должно возникнуть проблем с дальнейшим решением задачи.
Еще я бы как-нибудь обработал ситуацию с нулевыми элементами.
В чем именно проблема?

Это сообщение отредактировал(а) rudolfninja — 16.3.2016, 21:18

baldman88
Дата 16.3.2016, 23:20 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 1
Всего: 7

Код
#include «stdafx.h»
#include
#include
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
<
int n = 10;
int mas[n];
int positiv = 0;
int negativ = 0;
cout 0)
positiv++;
>
cout 0)
mas_p[positiv++] = mas[j];
if (mas[j]

disputant
Дата 18.3.2016, 12:00 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3

Код
int mas_p[positiv];
int mas_n[negativ];

Профиль
Группа: Участник
Сообщений: 26
Регистрация: 4.6.2015

Репутация: нет
Всего: нет

dreindeimos
Дата 18.3.2016, 14:36 (ссылка) | (нет голосов) Загрузка .
baldman88
Дата 18.3.2016, 17:07 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 1
Всего: 7

Код
#include «stdafx.h»
#include
#include
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
<
int n = 10;
int mas[n];
int positiv = 0;
int negativ = 0;
cout 0)
positiv++;
>
cout 0)
mas_p[positiv++] = mas[j];
if (mas[j]
disputant
Дата 18.3.2016, 21:18 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3

Цитата(baldman88 @ 18.3.2016, 17:07)
Дык, на дворе уже 2016 год. Или для лабораторных работ строго-настрого запрещено пользоваться С++11?

Берем последний Visual C++ 2015.

Код
int main(int argc, const char * argv[])
<
int mas[atoi(argv[1])];
>

Имеем: error C2131: выражение не определяется константой

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

baldman88
Дата 19.3.2016, 00:09 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 1
Всего: 7

Цитата(disputant @ 18.3.2016, 21:18)
Берем последний Visual C++ 2015.
Имеем: error C2131: выражение не определяется константой

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

Искренне Вам сочувствую . Свет не сошелся клином на поделиях MS.

Это сообщение отредактировал(а) baldman88 — 19.3.2016, 00:09

disputant
Дата 19.3.2016, 18:42 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3

Цитата(disputant @ 18.3.2016, 21:18)
Берем последний Visual C++ 2015.
Имеем: error C2131: выражение не определяется константой

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

Искренне Вам сочувствую . Свет не сошелся клином на поделиях MS.

А если вы по gcc — так в нем, на котором, видимо, у вас свет сошшелся, это расширение было уже очень давно.

Если вам не трудно, приведите еще 2-3 примера компиляторов, которые это скомпилируют. Просто чтоб понимать, до какой степени отстой этот Microsoft, и что все остальные давно умеют делать такие стандартные вещи.

Забавно, что отстойный сайт http://en.cppreference.com/w/cpp/language/array утверждает, что даже с C++14 там должно быть константное выражение, известное во время компиляции.

P.S. Полез в стандарт — п. 8.3.4,
In a declaration T D where D has the form
D1 [ constant-expressionopt] attribute-specifier-seqopt

Так что свет клином, надо понимать, и на стандарте не сошелся.

Это сообщение отредактировал(а) disputant — 19.3.2016, 19:01

baldman88
Дата 19.3.2016, 20:48 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 1
Всего: 7

Ваш ник говорит сам за себя Вы попросили назвать еще 2-3 примера компиляторов . Давайте начнем с того, что я знаю всего 4 самых распространенных компилятора. Остальное, субъективно, это экзотика. Вычтем из этих четырех озвученные Вами gcc и vc. Остается всего 2. Из них clang точно поддерживает. За интеловский ничего не скажу.
Дальше идем по линии идеологии.
С++, по идее, является надстройкой над С . Смотрим в стандарт С99 . (смотрят разработчики всех Нормальных компиляторов).
И да, эта дискуссия уже выходит далеко за рамки темы поста. Так что давайте не будем вдаваться в подробности.

Это сообщение отредактировал(а) baldman88 — 20.3.2016, 02:20

disputant
Дата 20.3.2016, 09:00 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 28.11.2011

Репутация: нет
Всего: 3

Цитата(baldman88 @ 19.3.2016, 20:48)
С++, по идее, является надстройкой над С . Смотрим в стандарт С99 . (смотрят разработчики всех Нормальных компиляторов).
И да, эта дискуссия уже выходит далеко за рамки темы поста. Так что давайте не будем вдаваться в подробности.

Даже Страуструп пишет, что очень большая ошибка — считать С++ расширением языка C.

А посему — особенно в ответах для начинающих и для переносимости — я считаю, что нужно использовать стандарт, а любые от него отклонения документировать

Что до последнего пожелания. Считаю, что как раз начинающим будет полезнее рассказывать, пусть и не подробно, но со всей строгостью закона. Да, это обычно трудно, но — взялся за гуж.

_zorn_
Дата 20.3.2016, 09:44 (ссылка) | (нет голосов) Загрузка .

Эксперт

Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 21.8.2007

Репутация: нет
Всего: 12

Цитата(disputant @ 20.3.2016, 16:00 )
я считаю, что нужно использовать стандарт
baldman88
Дата 20.3.2016, 23:40 (ссылка) | (нет голосов) Загрузка .

Бывалый

Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 1
Всего: 7

Цитата(disputant @ 20.3.2016, 09:00)
я считаю, что нужно использовать стандарт

Это конечно хорошо, что Вы так сведущи в стандарте. Я подробно его не читал (кроме некоторых моментов). Но для работы я по максимуму пользуюсь удобствами, предоставляемыми инструментами, которыми я пользуюсь. Ну и по порядку:
Во-первых, в данном случае озвученный выше функционал предоставляют два кроссплатформенных компилятора. То, что windows-only msvc этого не поддерживает, делает его еще менее привлекательным для реального использования.
Во-вторых, я привел два рабочих решения. Почему я их привел? ТС привел кусок кода. Значит он где-то его взял (написал сам, помогли друзья-товарищи, дал преподователь и сказал сделать задание, указанное в топике, и т.д. и т.п.). Если ТС хоть немного разбирается вопросе, то он сам до всего дойдет. Если нет, то и приведенные решения ему не помогут.

Это сообщение отредактировал(а) baldman88 — 21.3.2016, 09:33

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

Правила форума «C/C++: Для новичков»
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »

[ Время генерации скрипта: 0.1377 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Источник

Adblock
detector

AntonyV

0 / 0 / 0

Регистрация: 02.03.2013

Сообщений: 51

1

Разбор ошибки при выделении массива заданного размера

16.08.2017, 23:41. Показов 5381. Ответов 3

Метки нет (Все метки)


Вообщем пишу код конкатенации строк. Простейшее упражнение из Праты. Вводим фамилию, имя. Программа выводит фамилию, добавляет «,_», имя.
На строке с char summary[len]; вываливает ошибка c2131 expression did not evaluate to a constant
failure was cuased by a read of a variable outside its lifetime, see usage of len
По английски ясно. Но объясните в чем суть? Разве массиву обязательно указывать в [] размер — число-константу. Ок указал const int len = (strlen(last_name) + strlen(name) + 2 + 1); — То же самое.
И что значит переменная за пределами времени жизни? -Она же еще внутри блока.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <cstring>
 
using namespace std;
 
char *mem(void);
 
int main()
{
 
    cout << "Input ur last name: " << endl;
    char *last_name = mem();
 
    cout << "Input ur first name: " << endl;
    char *name = mem();
 
    int len = (strlen(last_name) + strlen(name) + 2 + 1);
        
    char summary[len];
 
    strcat(summary, last_name);
    strcat(summary, ", ");
    strcat(summary, name);
 
    cout << "Here's the information in a single string: " << endl;
    cout << summary;
 
    delete [] last_name;
    delete [] name;
 
 
    cin.get();
    cin.get();
    return 0;
 
}
 
char *mem()
 
{
 
    char in_section[20];
    cin.getline(in_section, 20);
    in_section[19] = ''; // or ''
 
    char *pn = new char[strlen(in_section) + 1];
 
    strcpy(pn, in_section);
    
    return pn;
 
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Croessmah

Don’t worry, be happy

17781 / 10545 / 2036

Регистрация: 27.09.2012

Сообщений: 26,516

Записей в блоге: 1

17.08.2017, 15:56

2

Лучший ответ Сообщение было отмечено AntonyV как решение

Решение

Цитата
Сообщение от AntonyV
Посмотреть сообщение

C++
1
char summary[len];

Размер массива должен быть константой времени компиляции.
У Вас он таковым не является, потому и ошибка.

C++
1
2
3
4
5
6
7
char *buffer = new char[strlen(last_name) + strlen(name) + 2 + 1];        
 
    strcpy(buffer , last_name);
    strcat(buffer , ", ");
    strcat(buffer , name);
//...
delete[] buffer;



2



0 / 0 / 0

Регистрация: 02.03.2013

Сообщений: 51

17.08.2017, 23:29

 [ТС]

3

Тааак, спасибо! Видимо я до этого еще в книжке не дошел.. Как я теперь понимаю нельзя во времени компиляции присваивать длины динамически выделенных массивов, так как их длина может быть любой во времени выполнения.



0



Don’t worry, be happy

17781 / 10545 / 2036

Регистрация: 27.09.2012

Сообщений: 26,516

Записей в блоге: 1

18.08.2017, 11:03

4



0



  • Forum
  • General C++ Programming
  • VS2019 16.10 constexpr

VS2019 16.10 constexpr

VS2019 16.10 is supposed to include support for the C++20 constexpr for std::string and std::vector. So why doesn’t this work? What have I overlooked??

1
2
3
4
5
6
7
8
9
#include <string>
#include <vector>

int main()
{
	constexpr std::string s {"qwe"};

	constexpr std::vector<int> vi {1, 2, 3, 4, 5};
}

1>Source.cpp
1>C:developvctest64Source.cpp(6,26): error C2131: expression did not evaluate to a constant
1>C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.29.30037includexstring(4602,50): message : failure was caused by allocated storage not being deallocated
1>C:developvctest64Source.cpp(8,32): error C2131: expression did not evaluate to a constant
1>C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.29.30037includevector(1711,47): message : failure was caused by allocated storage not being deallocated
1>c:developvcLibraryfiles.hpp(76,18): warning C4018: '<=': signed/unsigned mismatch
1>Done building project "test64.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Last edited on

Currently updating…

but does this help….
C++ Weekly — Ep 269 — How To Use C++20’s constexpr std::vector and std::string

From the standard for std::string constructor:


constexpr basic_string(const charT* s, const Allocator& a = Allocator());

So why can’t you have:

 
constexpr std::string s("foobar");

??

PS You can do this:

1
2
3
	constinit static const char* const cs[] {"qwe", "foo", "bar"};

	static_assert(std::size(cs) == 3);

but this doesn’t really give you anything as cs is built at compile time anyhow:

1
2
3
	const char* const cs[] {"qwe", "foo", "bar"};

	static_assert(std::size(cs) == 3);

Last edited on

My understanding is that you can construct a string in a constexpr context but the assigned storage can not be carried over to the runtime context. see around 6:10 in the video.

Yes. That seems to be about right from my testing. This compiles OK:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <vector>

constexpr auto f1() {
	const std::vector<int> vi {1, 2, 3};

	return vi.size();
}

int main()
{
	constexpr auto vs {f1()};

	static_assert(vs == 3);
}

So std::vector/std::string cannot be defined themselves as constexpr, but can be used within a constexpr context (eg constexpr function).

But this fails:

1
2
3
4
5
constexpr auto f1() {
	constexpr std::vector<int> vi {1, 2, 3};

	return vi.size();
}

so seems to confirm that can’t explicitly define a std::vector/std::string as constexpr.

So can’t define at compile time to be used at run-time. Ahh…

Last edited on

OK. So for compile time definition, you can use constexpr with std:array and c-style arrays and with c-style strings (char*) and with std::string_view but not with std::string or std::vector.

Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <array>
#include <string>

int main()
{
	constexpr std::array acs {"abc", "bar"};
	constexpr const char* const cs[] {"xyz", "foo"};

	constexpr std::array ant {1, 2, 3, 4, 5};
	constexpr const int ci[] {6, 7, 8};

	static_assert(cs[0][0] == 'x' && cs[1][1] == 'o');
	static_assert(acs[0][1] == 'b' && acs[1][2] == 'r');

	static_assert(ant[3] == 4);
	static_assert(ci[1] == 7);
}

Which compiles OK so the assertions are true at compile time, so the definitions are compile time.

Last edited on

Topic archived. No new replies allowed.

Понравилась статья? Поделить с друзьями:
  • Error c2109 subscript requires array or pointer type
  • Error c2106 левый операнд должен быть левосторонним значением
  • Error c2106 left operand must be l value
  • Error c2100 недопустимое косвенное обращение
  • Error c2100 illegal indirection