Я программирую в среде Visual Studio 2017 на C++14.
Проблема в том, что когда я пишу std::min
и std::max
, я получаю сообщение от компилятора «Требуется идентификатор». Это возникает из-за define, который подставляет вместо имён функций другой код.
Я использую библиотеки glad и glfw3 для работы с OpenGL, а сам define лежит в minwindef.h
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
Мне не хочется, чтобы этот define применялся к моему коду. Что я могу сделать?
αλεχολυτ
28.2k10 золотых знаков52 серебряных знака114 бронзовых знаков
задан 18 окт 2021 в 9:19
1
Начните программу со строки
#define NOMINMAX
Она отменяет макросы min
и max
в стандартных заголовочных файлах Windows.
ответ дан 18 окт 2021 в 10:36
HarryHarry
210k15 золотых знаков115 серебряных знаков224 бронзовых знака
Есть несколько способов решения проблемы макросов min
, max
в заголовочных файлах Windows.
-
Использовать
#define NOMINMAX
в коде перед явным или косвенным включением заголовочного файла с определением макросовmin
,max
. -
Иногда бывает не сразу очевидно, где именно стоит добавлять
#define NOMINMAX
, например, если добавление, казалось бы, в правильном месте не решает проблему. Тогда можно попробовать определитьNOMINMAX
через дополнительный ключ компилятора:> cl.exe -DNOMINMAX ...
В Visual Studio это делается через Configuration Properties → C/C++ → Preprocessor → Preprocessor Definitions в свойствах проекта.
-
При одновременном использовании библиотек, опирающихся на наличие функционала макросов
min
,max
, предыдущее решение может вызывать проблемы типа:error C3861: ‘min’: identifier not found
В таком случае можно дополнить первое решение внесением стандартных функций
std::min
,std::max
в проблемное пространство имён (откуда возникла ошибка «identifier not found»). Например:#define NOMINMAX #include <algorithm> namespace Gdiplus { using std::min; using std::max; }
-
Макросы
min
,max
можно вовсе не отменять, а вызовыstd::min
иstd::max
обернуть в скобки:(std::min)(x, y);
В таком виде макроподстановка не выполняется, т.к. для этого требуется иметь открывающую скобку (с возможными пробельными символами) сразу за потенциальным функциональным макросом, а мы это блокировали наличием закрывающей скобки.
-
Локально отменить макрос и после вызова функции вернуть с помощью
push_macro/pop_macro
:max(x, y); // Подстановка макроса #pragma push_macro("max") #undef max std::max(x, y); // Вызов функции #pragma pop_macro("max") max(x, y); // Снова подстановка макроса
ответ дан 19 окт 2021 в 7:55
αλεχολυταλεχολυτ
28.2k10 золотых знаков52 серебряных знака114 бронзовых знаков
- Remove From My Forums
-
Question
-
i am using a standard method max to find max of two arguments. When i compile the same code in VC9 i am getting this error.
Is this method defined somewhere else in the new compiler??
Regards,
Krishna
Answers
-
You’ve neglected to say which compiler/version you were using before,
and have not shown an example of your code which uses max.Have you tried this?
#include <algorithm>
std::max()
— Wayne
-
Marked as answer by
Wednesday, October 14, 2009 2:08 AM
-
Marked as answer by
-
Maybe
#include <windows.h>
-
Marked as answer by
Nancy Shao
Wednesday, October 14, 2009 2:08 AM
-
Marked as answer by
-
Hi Krishna,
- For max(), You have to include minmax.h .
- Yes! its a standard windows header.
- Me too had the problem in VC9 and atlast found this header.
Best Regards,
Jijo.
http://weseetips.com[^] Visual C++ tips and tricks. Updated daily.
-
Marked as answer by
Nancy Shao
Wednesday, October 14, 2009 2:08 AM
|
|
|
error C2143 и error C3861
, пропустил какой то include? Какой? Help!
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Junior Рейтинг (т): нет |
Изучаю C++ при помощи visual studio 2010 error C2143: syntax error : missing ‘)’ before ‘{‘ Путём упорного гугления кажется понял что не хватает какого то include. Какой надо подключить, подскажите пожалуйста? ещё пробовал подключить #include «stdlib.h» Всё без толку. ОС windows7 x64 |
aster_x |
|
А код примера можно посмотреть? |
Flass |
|
Junior Рейтинг (т): нет |
Однако, информация на буржуйском сайте помогла разобраться с min (error C3861) #include <stdio.h> и переправил min в __min Но ошибка error C2143: syntax error : missing ‘)’ before ‘{‘ пока не решена. Други, ну помогите кто нибудь, уже часа полтора лбом в закрытую дверь долблю. Добавлено 27.12.11, 14:52
void merge(int *A, int *B, int l, int m, int r) //A — сортируемый массив, B — буфер для слияния, l — первый элемент первой части, r — последний элемент второй части, m — последний элемент первой части { int i=l; int j = m+1; int k=l; //Вставлять минимальные элементы в B пока не кончится одна из последовательностей while (( i<=m) && (j<= r)) { if (A[i] { // РУГАЕТСЯ ВОТ ЗДЕСЬ B[k] = A[i]; i++; } else { B[k] = A[j]; j++; } k++; } //Скопировать остаток, если таковой имеется while (i <= m) { B[k]=A[i]; k++; i++; } while (j <= r) { B[k]=A[j]; k++; j++; } //Отсортированная часть остаётся в B } |
Сыроежка |
|
Цитата Flass @ 27.12.11, 14:27 Изучаю C++ при помощи visual studio 2010 error C3861: ‘min’: identifier not found Путём упорного гугления кажется понял что не хватает какого то include. Какой надо подключить, подскажите пожалуйста? ещё пробовал подключить #include «stdlib.h» Всё без толку. Все без толку, потому что вы не понимаете, что вы делаете. То есть вы используете имя min, а что это за имя, где ооно объявлено, и к чему оно относится, = вы не знаете. Более того эти два набора заголовков не совместимы между собой, так как первый набор заголовков относится к С++, а второй набор заголовков — к С. Добавлено 27.12.11, 15:05 Цитата Flass @ 27.12.11, 14:50 if (A[i] { // РУГАЕТСЯ ВОТ ЗДЕСЬ А синтаксическая ошибка у вас, к примеру, в указанном выше предложении. Вы забыли в if поставить закрывающуюся круглую скобку после выражения, состоящего из элемента массива. |
Flass |
|
Junior Рейтинг (т): нет |
Как я понял, min это функция в стандартной библиотеке, которую мы подключаем через include. Всё таки с min мне удалось разобраться. Поясните пожалуйста тогда, с учётом того что Visual Studio это всё таки C++, как должны выглядеть мои include? #include «iostream» Добавлено 27.12.11, 15:07 Цитата Сыроежка @ 27.12.11, 15:01 А синтаксическая ошибка у вас, к примеру, в указанном выше предложении. Вы забыли в if поставить закрывающуюся круглую скобку после выражения, состоящего из элемента массива. Миль пардон, но это текст примера и у автора всё работало… Такой синтаксис вполне законен, я думаю) Добавлено 27.12.11, 15:12 |
Сыроежка |
|
Цитата Flass @ 27.12.11, 15:05 Миль пардон, но это текст примера и у автора всё работало… Такой синтаксис вполне законен, я думаю) Если вы считаете, что такой код вполне законен, то все свои претензии предъявляйте к разработчику компилятора! Я вам ничем помочь не могу. |
Flass |
|
Junior Рейтинг (т): нет |
Что делать, я не копенгаген в C++, знаю только самые основы. Всё таки, с одной ошибкой мы разобрались, подскажите как решить вторую. Это пример работавшего у автора кода, дело в том что я не знаю какие он использовал include потому что приведён просто кусок кода и всё. Ёлки — палки, да как вообще такая ошибка может быть?) |
aster_x |
|
Попробуйте
if (A[i] { // РУГАЕТСЯ ВОТ ЗДЕСЬ Заменить на
if (A[i]) { |
Flass |
|
Junior Рейтинг (т): нет |
Цитата Flass @ 27.12.11, 15:17 Цитата aster_x @ 27.12.11, 15:17 Нет, я думаю дело не в этом. Если поступить как вы советуете, дальше при аналогичных ошибках и исправлении начинаются и вовсе странные вещи, например:
//Сортировка слиянием, распараллеленная void mp_sort(int* A, int* B, int N, int P) //A — сортируемый массив, B — буфер для слияния, N — размер массива, P — число параллельно выполняемых потоков { int *tA = A; int *tB = B; int *t = NULL; //1)Разбиение на блоки и сортировка их по отдельности int i; int part_size = (int)ceil((float)N/(float)P); #pragma omp parallel shared(P, tA, tB, N, part_size) #pragma omp for private(i) for(i=0;i {// ВОТ ЗДЕСЬ nrmsort(tA,tB,i*part_size,std::min((i+1)*part_size,N-1)); } int r2,m; while (part_size < (2*N))// а ещё почему то вайл подчёркнут красным, хотя в список ошибок не внесён. { #pragma omp parallel shared(P, tA, tB, N, part_size) #pragma omp for private(i,r2,m) for(i=0;i { r2 = std::min(i+part_size-1,N-1); m = ((i+i+part_size-1) >> 1); merge(tA,tB,i,m,r2); } part_size *= 2; t = tA; tA = tB; tB = t; t = NULL; } if (tA != A) { |
aster_x |
|
я на знаю где вы такой код нашли. Но он вообще не сответсвует не одному стандарту. Что это такое? Должно быть так, как минимум
for(i=0;;) Добавлено 27.12.11, 15:38 Сообщение отредактировано: aster_x — 27.12.11, 15:38 |
Flass |
|
Junior Рейтинг (т): нет |
То есть эти выражения полностью эквивалентны? |
aster_x |
|
Скорее всего этот «код» прошел какую то фильтрацию(наподобие обрезание HTML тегов), после чего пришел в «не употребительное» состояние. |
Flass |
|
Junior Рейтинг (т): нет |
http://www.hpcc.unn.ru/?dir=273 вот ссылка |
aster_x |
|
Цитата Flass @ 27.12.11, 15:39 То есть эти выражения полностью эквивалентны? Такого «for(i=0;i» выражения вообще нет в С++, это нарушение синтаксиса написания программы. Добавлено 27.12.11, 15:43 Добавлено 27.12.11, 15:46 Цитата aster_x @ 27.12.11, 15:41 for(i=0;i Попробуйте заменить на
for(i=0;i<N;++i) Сообщение отредактировано: aster_x — 27.12.11, 15:46 |
Flass |
|
Junior Рейтинг (т): нет |
Вот оно что!! Спасибо за подсказку, а то у меня уже мозги кипят) Добавлено 27.12.11, 15:53 Добавлено 27.12.11, 16:07 |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- C/C++: Общие вопросы
- Следующая тема
[ Script execution time: 0,0519 ] [ 16 queries used ] [ Generated: 9.02.23, 12:13 GMT ]
@SanderBouwhuis
GSL itself should be able to compile out of the box to be used in your applications without any sort of an additional overhead. Is it only when you’re trying to use it in conjunction with windows.h that you’re having issues or are you running into issues in general?
The reason for needing to define NOMINMAX
is to prevent macro expansion of all instances of the words min
and max
. You can think of the preprocessor as a really naive token replacement engine that just says «oh hey, it’s that max keyword thing! I better swap it out.» without taking any context into consideration. So you’ll even see compiler errors if you try invoking std::max from the algorithm
header. A search on Github finds about 450k instances of NOMINMAX
either surrounding Windows.h
includes or as a compile definition, so it’s by no means an isolated issue.
I’m not familiar with GSL-lite, though I had a quick look at it and found that they surround the numeric_limits max call with the parentheses just like how @andreduvoisin suggests to fix it in pr #817. I’m not sure how often the maintainer(s) of gsl-lite updates with changes from this repo or how far it’s diverged.
I am not sure why this is occuring. I declared these functions in the header file and it is defined them in the .cpp file but in the main function it does not recognize them. Did I forget something basic or do something illegal?
The errors:
: error C3861: ‘createAndInitializeTextFile’: identifier not found
: error C3861: ‘enterRecords’: identifier not found
: error C3861: ‘test’: identifier not found
: error C3861: ‘test’: identifier not found
: error C3861: ‘processChoice’: identifier not found
My code for the header file:
class Tools
{
public:
Tools(int = -1, string = "", int = 0, double = 0.0);
void setPartNumber(int);
int getPartNumber() const;
void setToolName(string);
string getToolName() const;
void setInStock(int);
int getInStock() const;
void setUnitPrice(double);
double getUnitPrice() const;
void createAndInitializeTextFile();
void enterRecords();
bool test();
void processChoice();
int enterChoice();
void printTextFile(fstream&);
void updateRecord(fstream&);
void newRecord( fstream& );
void deleteRecord( fstream& );
void outputLine( ostream&, const Tools & );
int getPart( const char * const );
private:
enum Choices { PRINT = 1, UPDATE, NEW, DELETE, END };
int partNumber;
char toolName[20];
int inStock;
double unitPrice;
};
Some parts of my member function definitions:
void Tools::enterRecords()
{
fstream outTools( "hardware.dat", ios::in | ios::out | ios::binary );
// exit program if fstream cannot open file
if ( !outTools )
{
cerr << "File could not be opened." << endl;
exit( 1 );
} // end if
cout << "Enter tool identification number (1 to 100, 0 to end input)n? ";
// require user to specify account number
Tools tool;
//cin >> partNumber;
partNumber = 3;
cout << " 3";
// user enters information, which is copied into file
while ( partNumber > 0 && partNumber <= 100 )
{
// user enters tool name, quantity and unit price
cout << "Enter the tool name, quantity in stock, and the unit price for the tooln? ";
//cin >> setw( 20 ) >> toolName;
//cin >> inStock;
//cin >> unitPrice;
toolName = "Electric Sander";
inStock = 7;
unitPrice = 57.98;
// set the record for the part number, tool name, quantity in stock, and unit price
tool.setPartNumber( partNumber );
tool.setToolName( toolName );
tool.setInStock( inStock );
tool.setUnitPrice( unitPrice );
// seek position in file of user-specified record
outTools.seekp( ( tool.getPartNumber() - 1 ) * sizeof ( Tools ) );
// write user-specified information in file
outTools.write( reinterpret_cast < const char * >( &tool ),sizeof ( Tools) );
// enable user to enter another account
//cout << "Enter account numbern? ";
//cin >> partNumber;
} // end while
}
bool Tools::test()
{
ifstream inTools( "hardware.dat", ios::in | ios::binary );
// exit program if ifstream cannot open file
if ( !inTools )
{
cerr << "File could not be opened." << endl;
exit( 1 );
} // end if
Tools tool;
bool answer = false;
if ( tool.getPartNumber() != 0 )
answer = true;
else
answer = false;
return answer;
}
My code in .cpp main function, where the error is occurring:
#include "Tools.h"
int main()
{
createAndInitializeTextFile();
enterRecords();
test();
if(test())
{
"Hardware program successful.";
processChoice();
}
else
{
"Hardware program failed.";
}
cout << endl;
return 0;
}
Я только начал новый win32
консольное приложение в VS 2010 и установить Additional options
собственность на precompiled header
в предстоящем мастере.
На основе один из моих предыдущих вопросов Я решил использовать следующий основной прототип:
int main(int argc, char* argv[])
Я также изменил Character Set
свойство проекта к Use Multi-Byte Character Set
,
Но следующий код:
system("pause");
Будет выдавать эти две ошибки:
error C3861: 'system': identifier not found
IntelliSense: identifier "system" is undefined
У меня был такой же опыт, и ошибок не было!
Кто-нибудь может подсказать мне, что не так?
2
Решение
В C ++ вы должны включить соответствующий заголовочный файл, который содержит объявление функции, чтобы использовать ее, иначе вы получите ошибку компилятора о том, что идентификатор не найден.
В случае с system
функция, это определено в stdlib.h
заголовочный файл
Итак, в начало вашего файла кода (или в вашем предварительно скомпилированном заголовочном файле) добавьте строку
#include <stdlib.h>
(Вы используете угловые скобки вместо кавычек, потому что stdlib.h
найден ли заголовок в том месте, о котором ранее сообщалось инструменту сборки; это включает в себя каталоги системных заголовков и другие каталоги, которые ваша конфигурация сборки специально требует.)
Помимо этого я сильно рекомендую против используя либо многобайтовый набор символов (все новые приложения Windows должны поддерживать Unicode), либо system
функция, особенно system("pause")
,
7
Другие решения
Для меня работало то, что #include "stdafx.h"
был ПЕРВЫЙ ВКЛЮЧЕН в файл. Так #include <iostream>
поэтому будет после этого.
Это решило проблему.
3
I’m working on a program that was written by someone else. It is for a research project that builds on the original author’s work.
I didn’t know any c++ before I started, but I know enough about programming to get by for the most part. The problem I’m having at the moment is this:
The code as it is produces 3 voxel grids with the values representing the x, y, and z components of the vector potential of a dipole at the origin respectively. I want to modify the code so that it produces the vector potential of two dipoles, separated by a distance.
The functions that produces the dipole is in a header file. I simply copied the dipole function and renamed it, then altered the code in the renamed version. I wanted to keep the original in there so I could easily call whichever one I wanted.
The problem is that I get an «identifier not found» error when I build the code. I get the same problem for each component of the vector potential, so I will only post the code for one.
The function is called in the main function like this
Dipole_TS_theta4(TS_Proj1, ny, lx, ly, lz, rad_sup);
|
|
|
|
I also just noticed that I get the problem even if I only call the original functions (they don’t have the 4 at the end of the name) unless I delete my new attempted definitions from the pvrt.cpp file. If I remove them the code compiles and runs properly. I’ve tried searching but it always turns out to be a typo or something that causes the error, and I can’t see a typo in my code. Hopefully someone can help out. Thanks in advance