2011-02-06 12 views
28

Jakie problemy można napotkać podczas definiowania NOMINMAX przed czymkolwiek innym w moim programie?Możliwe problemy z NOMINMAX w Visual C++

Z tego, co wiem, spowoduje to, że <Windows.h> nie zdefiniuje makr typu min i max w taki sposób, że wiele konfliktów ze STL, np. std::min(), std::max() lub std::numeric_limits<T>::min() zostały rozwiązane.

Czy mam rację, zakładając, że tylko specyficzny dla systemu Windows i starszy kod będą mieć problemy? Prawie wszystkie biblioteki nie powinny być zależne od min() i max() zdefiniowanych jako makra?

Edycja: Czy wystąpią problemy z innymi nagłówkami systemu Windows?

+1

nie powinno być problemów, nawet z Windows konkretnego kodu, ale jest to możliwe że istnieje jakiś kod, który nie działa. Dlaczego nie spróbujesz i zobaczysz, czy są jakieś błędy? –

+0

Dla naszego wewnętrznego kodu, 'NOMINMAX' działa dobrze. Jednak biblioteka jest również używana przez zewnętrznych programistów i nie chcę łamać ich aplikacji. – Manuel

+1

'# define' jest operacją w czasie kompilacji. Biblioteki są połączone, a nie kompilowane. Oznacza to, że mogą mieć własne niezależne '# define's. Użytkownicy bibliotek nie zobaczą, że '# define'd' NOMINMAX' – MSalters

Odpowiedz

47

Używanie NOMINMAX jest jedynym niezupełnie złym sposobem na dodanie <windows.h>. Powinieneś także zdefiniować UNICODE i STRICT. Chociaż ten ostatni jest domyślnie zdefiniowany przez nowoczesne implementacje.

Można jednak napotkać problemy z nagłówkami Microsoft ’, np. dla GdiPlus. I ’ m nie zdaje sobie sprawy z problemów z nagłówkami od innych firm lub osób.

Jeśli nagłówek definiuje przestrzeń nazw, tak jak GDIPlus, a następnie jeden fix jest stworzenie opakowania dla odpowiedniego nagłówka, gdzie można zawierać <algorithm>, a wewnątrz nagłówka ’ s nazw, using namespace std; (lub alternatywnie using std::min; i using std::max):

#define NOMINMAX 
#include <algorithm> 
namespace Gdiplus 
{ 
    using std::min; 
    using std::max; 
} 

należy pamiętać, że to jest bardzo różni się od using namespace std; w zakresie globalnym w nagłówku, który nigdy nie powinien zrobić.

I don ’ I wiem o jakimkolwiek dobrym obejściu dla przypadku, w którym nie ma obszaru nazw, ale szczęśliwie mam ’ t na to, więc w praktyce ten konkretny problem jest prawdopodobnie dyskusyjny.

+1

W przypadku GdiPlus problem można rozwiązać? – Manuel

+1

@ Manuel: tak, widocznie. Muszę zawrzeć kwalifikację słowem łasce "najwyraźniej", ponieważ podczas gdy to działa dobrze dla tego, co zrobiłem, nie mogę zagwarantować, że nie ma jakiegoś złego kodu GdiPlus, którego nie ćwiczyłem. Gdzieś. –

+0

Innym rozwiązaniem jest po prostu pobudzenie go z 'min',' max' programu STL i pozwolić kompilatorowi użyć 'min',' max' Windef.h dla twoich projektów GDIPlus. Nic takiego. – bobobobo

11

ja zazwyczaj używają NOMINMAX tak, aby ograniczyć potencjalne skutki uboczne:

#define NOMINMAX 
#include <windows.h> 
#undef NOMINMAX 

ten sposób zakres NOMINMAX jest stosunkowo ograniczony.

To nie jest idealne rozwiązanie. Jeśli coś innego już zdefiniowało NOMINMAX, ten wzór się nie udał (chociaż nigdy nie spotkałem się z takim przypadkiem).

Jeśli chcesz być naprawdę, bardzo ostrożny, to możesz # zawrzeć nagłówek opakowania, gdziekolwiek był #included windows.h. Owijka pójdzie coś takiego:

/* Include this file instead of including <windows.h> directly. */ 
#ifdef NOMINMAX 
#include <windows.h> 
#else 
#define NOMINMAX 
#include <windows.h> 
#undef NOMINMAX 
#endif 

Można wyobrazić sobie inne rzeczy w opakowaniu, też, jak egzekwowanie UNICODE i/lub STRICT.

0

Dla prekompilowanego nagłówka (np. Stdafx.h) Używam tego:

#define NOMINMAX 
#include <algorithm> 
#include <Windows.h> 
#ifndef min 
#define min(x,y) ((x) < (y) ? (x) : (y)) 
#endif 
#ifndef max 
#define max(x,y) ((x) > (y) ? (x) : (y)) 
#endif 
#include <gdiplus.h> 
#undef min 
#undef max 
0

Mam problem fix deklarując nagłówki i nazw w następującej kolejności:

#include <windows.h> 
#include <minmax.h> 
#include <gdiplus.h> 

using namespace Gdiplus; 
using namespace std; 
Powiązane problemy