Bagaimana saya mencegah memasukkan file header dua kali? Masalahnya adalah saya termasukdi MyClass.h dan kemudian saya termasuk MyClass.h dalam banyak file, jadi itu termasuk beberapa kali dan terjadi redefinisi kesalahan. Bagaimana cara mencegahnya?
Saya menggunakan #pragma sekali alih-alih menyertakan penjaga, dan saya kira itu tidak masalah.
MyClass.h:
// MyClass.h
#pragma once
#include <winsock2.h>
class MyClass
{
// methods
public:
MyClass(unsigned short port);
virtual ~MyClass(void);
};
EDIT: Beberapa kesalahan yang saya dapatkan
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(91) : warning C4005: 'AF_IPX' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(460) : see previous definition of 'AF_IPX'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(124) : warning C4005: 'AF_MAX' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(479) : see previous definition of 'AF_MAX'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(163) : warning C4005: 'SO_DONTLINGER' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(402) : see previous definition of 'SO_DONTLINGER'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(206) : error C2011: 'sockaddr' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(485) : see declaration of 'sockaddr'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2143: syntax error : missing '}' before 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2143: syntax error : missing ';' before 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(384) : error C2059: syntax error : 'constant'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C2143: syntax error : missing ';' before '}'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(437) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(518) : warning C4005: 'IN_CLASSA' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(287) : see previous definition of 'IN_CLASSA'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(524) : warning C4005: 'IN_CLASSB' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(293) : see previous definition of 'IN_CLASSB'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(530) : warning C4005: 'IN_CLASSC' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(299) : see previous definition of 'IN_CLASSC'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(541) : warning C4005: 'INADDR_ANY' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(304) : see previous definition of 'INADDR_ANY'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(543) : warning C4005: 'INADDR_BROADCAST' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(306) : see previous definition of 'INADDR_BROADCAST'
c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h(577) : error C2011: 'sockaddr_in' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(312) : see declaration of 'sockaddr_in'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(132) : error C2011: 'fd_set' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(68) : see declaration of 'fd_set'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(167) : warning C4005: 'FD_SET' : macro redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(102) : see previous definition of 'FD_SET'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(176) : error C2011: 'timeval' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(111) : see declaration of 'timeval'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(232) : error C2011: 'hostent' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(167) : see declaration of 'hostent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(245) : error C2011: 'netent' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(180) : see declaration of 'netent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(252) : error C2011: 'servent' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(187) : see declaration of 'servent'
c:\program files\microsoft sdks\windows\v6.0a\include\winsock2.h(264) : error C2011: 'protoent' : 'struct' type redefinition
c:\program files\microsoft sdks\windows\v6.0a\include\winsock.h(199) : see declaration of 'protoent'
c++
header
redefinition
akif
sumber
sumber
Jawaban:
Masalah ini disebabkan ketika termasuk
<windows.h>
sebelumnya<winsock2.h>
. Coba atur daftar sertakan Anda yang<windows.h>
disertakan setelah<winsock2.h>
atau tetapkan_WINSOCKAPI_
dulu:Lihat juga ini .
sumber
<winsock2.h>
di MSVC2008.<windows.h>
inklusi membuatnya menghasilkan kesalahan kompilasi yang sama seperti yang Anda berikan.#include <winsock2.h> #include <ws2tcpip.h> #include <windows.h>
dalam rangka dan mendapatkan winsock2, file h tidak ditemukan. Termasuk di#define _WINSOCKAPI_
atas semua 3 termasuk masih kesalahan yang samaSeperti yang disarankan orang lain, masalahnya adalah kapan
windows.h
dimasukkan sebelumnyaWinSock2.h
. Karenawindows.h
termasukwinsock.h
. Anda tidak dapat menggunakan keduanyaWinSock2.h
danwinsock.h
.Solusi:
Sertakan
WinSock2.h
sebelumnyawindows.h
. Dalam kasus tajuk yang dikompilasi, Anda harus menyelesaikannya di sana. Dalam kasus proyek sederhana, itu mudah. Namun dalam proyek-proyek besar (terutama ketika menulis kode portabel, tanpa header yang dikompilasi) itu bisa sangat sulit, karena ketika header AndaWinSock2.h
disertakan,windows.h
dapat sudah disertakan dari beberapa header lain / file implementasi.Tentukan
WIN32_LEAN_AND_MEAN
sebelumwindows.h
atau luas proyek. Tapi itu akan mengecualikan banyak hal lain yang mungkin Anda butuhkan dan Anda harus memasukkannya sendiri.Tentukan
_WINSOCKAPI_
sebelumwindows.h
atau luas proyek. Tetapi ketika Anda termasukWinSock2.h
Anda mendapatkan peringatan redefinisi makro.Gunakan
windows.h
alih-alihWinSock2.h
kapanwinsock.h
cukup untuk proyek Anda (dalam banyak kasus itu). Ini mungkin akan menghasilkan waktu kompilasi yang lebih lama tetapi menyelesaikan kesalahan / peringatan.sumber
WIN32_LEAN_AND_MEAN
adalah solusi bagi saya banyak tank_WINSOCK_
solusi: Anda tidak boleh grt peringatan redefinisi makro jika kedua definisi sama. Bug umum adalah bahwa orang menambahkan definisi ke proyek tanpa menetapkan nilai apa pun dan mengharapkan definisi kosong. Namun, jika Anda menambahkan-D_WINSOCK_
ke baris cmd, itu akan diatur_WINSOCK_
ke 1. Untuk membuat definisi kosong,-D_WINSOCK_=
harus diteruskan.#define _WINSOCKAPI_
, Anda mungkin juga perlu#define _WINSOCK_DEPRECATED_NO_WARNINGS
, tergantung pada keadaan Anda.Oh - keburukan Windows ... Urutan termasuk penting di sini. Anda harus memasukkan winsock2.h sebelum windows.h. Karena windows.h mungkin disertakan dari tajuk yang sudah dikompilasi sebelumnya (stdafx.h), Anda harus menyertakan winsock2.h dari sana:
sumber
Dengan menggunakan "penjaga tajuk":
sumber
Saya mengalami masalah ini ketika mencoba menarik paket pihak ketiga yang ternyata termasuk windows.h di suatu tempat di dalamnya berantakan header. Mendefinisikan
_WINSOCKAPI_
di tingkat proyek jauh lebih mudah (belum lagi lebih dapat dipelihara) daripada mengarungi sup mereka dan memperbaiki termasuk yang bermasalah.sumber
DEFINES += _WINSOCKAPI_
Dalam VS 2015, yang berikut ini akan berfungsi:
Sementara yang berikut tidak akan:
sumber
Aku memeriksa rekursif meliputi, aku melihat file header yang meliputi (rekursif) beberapa
#include "windows.h"
dan#include "Winsock.h"
dan menulis#include "Winsock2.h"
. dalam file ini, saya menambahkan#include "Winsock2.h"
sebagai yang pertama termasuk.Hanya masalah kesabaran, lihat termasuk satu per satu dan tentukan urutan ini, pertama
#include "Winsock2.h"
kemudian#include "windows.h"
sumber
Saya menemukan tautan ini windows.h dan winsock2.h yang memiliki alternatif yang bekerja sangat baik bagi saya:
Saya mengalami kesulitan menemukan di mana masalah terjadi tetapi dengan menambahkan bahwa #define saya dapat membangun tanpa mencari tahu.
sumber
Saya tidak akan menggunakan FILENAME_H saja tetapi
Saya selalu menggunakan panduan postfix. Saya menemukan basis kode yang sangat buruk beberapa tahun yang lalu yang memiliki file header yang berbeda dengan nama file yang sama dan termasuk penjaga. File-file tersebut telah mendefinisikan kelas dengan nama yang sama. Jika hanya ruang nama yang digunakan. Beberapa proyek yang dikompilasi tidak. Menggunakan penjaga unik adalah bagian dari solusi dalam membedakan header dan isinya.
Pada Windows dengan Visual Studio gunakan guidgen.exe, di Linux uuidgen -t.
sumber
Saya telah mengalami masalah yang sama dan inilah yang saya temukan sejauh ini:
Dari fragmen output ini -
-Tampak bahwa ws2def.h dan winsock.h telah dimasukkan dalam solusi Anda.
Jika Anda melihat file ws2def.h ini dimulai dengan komentar berikut -
Perhatikan baris terakhir - "File ini tidak bisa dimasukkan oleh modul yang juga termasuk WINSOCK.H"
Masih berusaha memperbaiki masalah tanpa membuat perubahan pada kode.
Beri tahu saya jika ini masuk akal.
sumber
Anda harus menggunakan pelindung tajuk.
letakkan baris itu di bagian atas file header
dan di bagian bawah
sumber
#pragma once
didasarkan pada path lengkap dari nama file. Jadi yang mungkin Anda miliki adalah ada dua salinan identik dari MyClass.h atau Winsock2.h di direktori yang berbeda.sumber
#pragma once
flakey, bahkan pada kompiler MS, dan tidak didukung oleh banyak kompiler lain. Seperti banyak orang lain telah menyebutkan, menggunakan penjaga termasuk adalah cara untuk pergi. Jangan gunakan#pragma once
sama sekali - itu akan membuat hidup Anda lebih mudah.sumber
#pragma once
, kompiler mengambil nama simpul file header sebagai Id unik. Ini bisa gagal jika Anda memiliki tautan simbolis atau persimpangan NTFS di pohon sumber Anda (lebih umum daripada yang Anda kira), atau bahkan jika Anda memiliki file dengan nama yang sama di sistem lain termasuk direktori (ini telah terjadi pada saya sebelumnya ketika saya memiliki versi 1 dan versi 2 dari perpustakaan yang sama diinstal ke dua sistem yang berbeda termasuk jalur). Intinya: bagi saya, saya lebih suka memiliki kontrol lebih, dan hidup dengan kesalahan wetware sesekali, daripada percaya kompiler untuk melakukannya untuk saya.#sertakan penjaga adalah cara standar untuk melakukan ini. #pragma sekali tidak, artinya tidak semua kompiler mendukungnya.
sumber
Dalam proyek saya (saya menggunakan VS 2008 SP1) bekerja solusi berikut:
File tajuk:
Kelas Cpp:
di mana #include "winsock2class.h" kelas rata-rata yang menerapkan winsock2.h:
sumber
Saya benar-benar mengalami masalah di mana saya harus mendefinisikan winsock2.h sebagai termasuk pertama, tampaknya memiliki masalah lain dengan menyertakan dari paket lain. Semoga ini bermanfaat bagi seseorang yang mengalami masalah yang sama, tidak hanya windows.h tetapi semua termasuk.
sumber