Redefinition of custom delete - c++
I am getting an error saying that I have redefined a function custom_delete.
header.h
#include <iostream>
#include <string>
static int unfreed_count = 0;
#define DELETE(O) custom_delete(O,__PRETTY_FUNCTION__, __LINE__)
void custom_delete(void* ptr, const std::string& function_name, unsigned int line_number) {
unfreed_count--;
std::cout << "delete called in " + function_name + ":" << line_number << std::endl;
std::cout << "unfreed_count: = " << unfreed_count << std::endl << std::endl;
free(ptr);
}
main.cpp
#include "header.h"
int main(int argc, char* argv[]) {
int* ptr = new int;
DELETE(ptr);
}
This code results in the following error message upon attempted compilation:
main.cpp: In function 'void custom_delete(void*, const string&, unsigned int)':
main.cpp:5:6: error: redefinition of 'void custom_delete(void*, const string&, unsigned int)'
void custom_delete(void* ptr, const std::string& function_name, unsigned int line_number) {
^
In file included from main.cpp:21:0:
header.h:7:6: note: 'void custom_delete(void*, const string&, unsigned int)' previously defined here
void custom_delete(void* ptr, const std::string& function_name, unsigned int line_number) {
^
I was trying to make a custom version of delete that printed out when it was used. This was in a larger project, so I made a separate project with just these two files and got the same errors.
I tried commenting out all the code inside the custom_delete function. I also tried writing the prototype before the macro. I got the same error each time.
---EDIT---
I found there was another file being compiled:
header.cpp
#include "header.h"
// Some commented out functions
If I remove the #include "header.h" everything works. However, I eventually will need to add the functions to header.cpp. These functions need stuff that will be added to header.h. What should I do?
It looks like you don't have include guard in your headers.
Add #pragma once as the first line of your header.h
or for more portable solution, add
#ifndef HEADER_H
#define HEADER_H
as first two lines, and
#endif
as last line of the header.h.
Also, to avoid link errors, add inline keyword to declaration of your function, like inline void custom_delete(...
or move function implementation to .cpp.
Related
Invalid use of non-static data member for accesing array in a struct
I am trying to work with JUCE Demo, and extract portions of BinaryData.cpp and OpenGLDemo.cpp into my own class. Unfortunately, I run into a problem I can't really parse, which I've managed to reduce in this minimal example of three files: main.cpp, mystuff.cpp and mystuff.h: main.cpp: // g++ -std=c++11 main.cpp mystuff.cpp -o main #include "mystuff.h" int main(int argc, char* argv[]) { MyStuff tmpstuff; std::cout << "hello world" << tmpstuff.temp_binary_data_7[0] << std::endl ; } mystuff.h #include <iostream> class MyStuff { public: MyStuff(); ~MyStuff(); // from BinaryData.cpp: //~ static const unsigned char temp_binary_data_7[] = //~ { 35,32,77,97,120,50,79,98,106,32,86,101,114,115,105,111,110,32,52,46,48,32,77,97,114,32,49,48,116,104,44,32,50,48,48,49,10,35,10,35,32,111,98,106,101,99,116,32,84,101,97,112,111,116,48,49,32,116,111,32,99,111,109,101,32,46,46,46,10,35,10,118,32,32,53, //~ 46,57,50,57,54,56,56,32,52,46,49,50,53,48,48,48,32,48,46,48,48,48,48,48,48,10,118,32,32,53,46,56,51,50,48,51,49,32,52,46,52,57,52,49,52,49,32,48,46,48,48,48,48,48,48,10,118,32,32,53,46,57,52,53,51,49,51,32,52,46,54,49,55,49,56,56,32,48,46,48,48,48,48, //~ 48,48,10,118,32,32,54,46,49,55,53,55,56,49,32,52,46,52,57,52,49,52,49,32,48,46,48,48,48,48,48,48,10,118,32,32,54,46,52,50,57,54,56,56,32,52,46,49,50,53,48,48,48,32,48,46,48,48,48,48,48,48,10,118,32,32,53,46,51,56,55,49,56,56,32,52,46,49,50,53,48,48,48 //~ }; // move definition to .cpp because of 'error: in-class initialization of static data member ‘const unsigned char MyStuff::temp_binary_data_7 []’ of incomplete type' static const unsigned char temp_binary_data_7[]; const char* teapot_obj = (const char*) temp_binary_data_7; // from OpenGLDemo.cpp: struct Shape { Shape() { std::cout << "initializing " << static_cast<void*>(teapot_obj) << std::endl ; } }; }; mystuff.cpp: #include "mystuff.h" const unsigned char MyStuff::temp_binary_data_7[] = { 35,32,77,97,120,50,79,98,106,32,86,101,114,115,105,111,110,32,52,46,48,32,77,97,114,32,49,48,116,104,44,32,50,48,48,49,10,35,10,35,32,111,98,106,101,99,116,32,84,101,97,112,111,116,48,49,32,116,111,32,99,111,109,101,32,46,46,46,10,35,10,118,32,32,53, 46,57,50,57,54,56,56,32,52,46,49,50,53,48,48,48,32,48,46,48,48,48,48,48,48,10,118,32,32,53,46,56,51,50,48,51,49,32,52,46,52,57,52,49,52,49,32,48,46,48,48,48,48,48,48,10,118,32,32,53,46,57,52,53,51,49,51,32,52,46,54,49,55,49,56,56,32,48,46,48,48,48,48, 48,48,10,118,32,32,54,46,49,55,53,55,56,49,32,52,46,52,57,52,49,52,49,32,48,46,48,48,48,48,48,48,10,118,32,32,54,46,52,50,57,54,56,56,32,52,46,49,50,53,48,48,48,32,48,46,48,48,48,48,48,48,10,118,32,32,53,46,51,56,55,49,56,56,32,52,46,49,50,53,48,48,48 }; MyStuff::MyStuff() { } MyStuff::~MyStuff() { } When I compile with g++, I get this: $ g++ -std=c++11 main.cpp mystuff.cpp -o main In file included from main.cpp:3:0: mystuff.h: In constructor ‘MyStuff::Shape::Shape()’: mystuff.h:18:42: error: invalid use of non-static data member ‘MyStuff::teapot_obj’ const char* teapot_obj = (const char*) temp_binary_data_7; ^ mystuff.h:25:58: error: from this location std::cout << "initializing " << static_cast<void*>(teapot_obj) << std::endl ; ^ In file included from mystuff.cpp:1:0: mystuff.h: In constructor ‘MyStuff::Shape::Shape()’: mystuff.h:18:42: error: invalid use of non-static data member ‘MyStuff::teapot_obj’ const char* teapot_obj = (const char*) temp_binary_data_7; ^ mystuff.h:25:58: error: from this location std::cout << "initializing " << static_cast<void*>(teapot_obj) << std::endl ; ^ This happens only when the struct Shape code exists in mystuff.h - if you delete it, then the code compiles and runs fine. So what are my options? How can I define the struct Shape (or the other variables) so that it can refer to teapot_obj without compilation errors?
Ok, managed to fix it by just throwing expressions here and there, but it would still be great to read an answer that explains what is actually going on... here are my changes - only in mystuff.h: mystuff.h: #include <iostream> class MyStuff { public: MyStuff(); ~MyStuff(); static const unsigned char temp_binary_data_7[]; static constexpr const char* teapot_obj = (const char*) temp_binary_data_7; // from OpenGLDemo.cpp: struct Shape { Shape() { std::cout << "initializing " << static_cast<const void*>(teapot_obj) << std::endl ; } }; Shape tmptest; }; So, basically: const char* teapot_obj = (const char*) temp_binary_data_7; had to change into: static constexpr const char* teapot_obj = (const char*) temp_binary_data_7; ... which then means I have to make a static_cast<const void*> (instead of just static_cast<void*>) to print out the object address; and finally, have to add a Shape tmptest; so that the constructor of Shape runs at least once, so we can have something printed. And now, the program runs without problems: $ g++ -std=c++11 main.cpp mystuff.cpp -o main $ ./main initializing 0x400c60 hello world#
Redefinition of a class in a header file
I'm attempting to compile my code with g++, but its throwing this compiler error: Enrollment.h:3:7: error: redefinition of class sict::Enrollment Enrollment.h:3:7: error: previous definition of class sict::Enrollment my Enrollment.h: namespace sict{ class Enrollment{ private: char _name[31]; char _code[11]; int _year; int _semester; int _slot; bool _enrolled; public: Enrollment(const char* name , const char* code, int year, int semester , int time ); Enrollment(); void set(const char* , const char* , int ,int, int , bool = false ); void display(bool nameOnly = false)const; bool valid()const; void setEmpty(); bool isEnrolled() const; bool hasConflict(const Enrollment &other) const; }; } Any way to fix this?
The problem is likely that your header file is included (directly and indirectly) in the same translation unit. You should use some way of avoiding the multiple includes of the same header file in your cpp's. I prefer #pragma once in the beginning of your header file - it is not standard but it is supported by all major compilers. Otherwise you can go for good-old include guards: #ifndef _Enrollment_h_ #define _Enrollment_h_ // Your header contents here #endif or with pragma: #pragma once // Your header contents here
You need to use some include guards. Either #pragma once or: #ifndef MY_FILE_H #define MY_FILE_H .... #endif //MY_FILE_H This is to prevent the same code being included in every file where you include this header (double inclusion). This will essentially help out the pre-processor. More information here.
How to declare constexpr extern?
Is it possible to declare a variable extern constexpr and define it in another file? I tried it but the compiler gives error: Declaration of constexpr variable 'i' is not a definition in .h: extern constexpr int i; in .cpp: constexpr int i = 10;
no you can't do it, here's what the standard says (section 7.1.5): 1 The constexpr specifier shall be applied only to the definition of a variable or variable template, the declaration of a function or function template, or the declaration of a static data member of a literal type (3.9). If any declaration of a function, function template, or variable template has a constexpr specifier, then all its declarations shall contain the constexpr specifier. [Note: An explicit specialization can differ from the template declaration with respect to the constexpr specifier. Function parameters cannot be declared constexpr. — end note ] some examples given by the standard: constexpr void square(int &x); // OK: declaration constexpr int bufsz = 1024; // OK: definition constexpr struct pixel { // error: pixel is a type int x; int y; constexpr pixel(int); // OK: declaration }; extern constexpr int memsz; // error: not a definition
C++17 inline variables This awesome C++17 feature allow us to: conveniently use just a single memory address for each constant store it as a constexpr do it in a single line from one header main.cpp #include <cassert> #include "notmain.hpp" int main() { // Both files see the same memory address. assert(¬main_i == notmain_func()); assert(notmain_i == 42); } notmain.hpp #ifndef NOTMAIN_HPP #define NOTMAIN_HPP inline constexpr int notmain_i = 42; const int* notmain_func(); #endif notmain.cpp #include "notmain.hpp" const int* notmain_func() { return ¬main_i; } Compile and run: g++ -c -o notmain.o -std=c++17 -Wall -Wextra -pedantic notmain.cpp g++ -c -o main.o -std=c++17 -Wall -Wextra -pedantic main.cpp g++ -o main -std=c++17 -Wall -Wextra -pedantic main.o notmain.o ./main GitHub upstream. The C++ standard guarantees that the addresses will be the same. C++17 N4659 standard draft 10.1.6 "The inline specifier": 6 An inline function or variable with external linkage shall have the same address in all translation units. cppreference https://en.cppreference.com/w/cpp/language/inline explains that if static is not given, then it has external linkage. See also: How do inline variables work? Tested in GCC 7.4.0, Ubuntu 18.04.
What you probably want is extern and constexpr initialization, e.g.: // in header extern const int g_n; // in cpp constexpr int g_n = 2; This is support though in Visual Studio 2017 only through conformance mode: /Zc:externConstexpr (Enable extern constexpr variables) constexpr definition of extern const variable
No. Extern constexpr does not make any sense. Please read http://en.cppreference.com/w/cpp/language/constexpr i.e. the bit it must be immediately constructed or assigned a value.
I agree with 'swang' above, but there is a consequence. Consider: ExternHeader.hpp extern int e; // Must be extern and defined in .cpp otherwise it is a duplicate symbol. ExternHeader.cpp #include "ExternHeader.hpp" int e = 0; ConstexprHeader.hpp int constexpr c = 0; // Must be defined in header since constexpr must be initialized. Include1.hpp void print1(); Include1.cpp #include "Include1.hpp" #include "ExternHeader.hpp" #include "ConstexprHeader.hpp" #include <iostream> void print1() { std::cout << "1: extern = " << &e << ", constexpr = " << &c << "\n"; } Include2.hpp void print2(); Include2.cpp #include "Include2.hpp" #include "ExternHeader.hpp" #include "ConstexprHeader.hpp" #include <iostream> void print2() { std::cout << "2: extern = " << &e << ", constexpr = " << &c << "\n"; } main.cpp #include <iostream> #include "Include1.hpp" #include "Include2.hpp" int main(int argc, const char * argv[]) { print1(); print2(); return 0; } Which prints: 1: extern = 0x1000020a8, constexpr = 0x100001ed0 2: extern = 0x1000020a8, constexpr = 0x100001ed4 IE the constexpr is allocated twice whereas the extern is allocated once. This is counterintuitive to me, since I 'expect' constexpr to be more optimized than extern. Edit: const and constexpr have the same behaviour, with regard to allocation, therefore from that point of view the behaviour is as expected. Though, as I said, I was surprised when I came across the behaviour of constexpr.
Yes it somewhat is... //=================================================================== // afile.h #ifndef AFILE #define AFILE #include <cstddef> #include <iostream> enum class IDs { id1, id2, id3, END }; // This is the extern declaration of a **constexpr**, use simply **const** extern const int ids[std::size_t(IDs::END)]; // These functions will demonstrate its usage template<int id> void Foo() { std::cout << "I am " << id << std::endl; } extern void Bar(); #endif // AFILE //=================================================================== // afile.cpp #include "afile.h" // Here we define the consexpr. // It is **constexpr** in this unit and **const** in all other units constexpr int ids[std::size_t(IDs::END)] = { int(IDs::id1), int(IDs::id2), int(IDs::id3) }; // The Bar function demonstrates that ids is really constexpr void Bar() { Foo<ids[0] >(); Foo<ids[1] + 123>(); Foo<ids[2] / 2 >(); } //=================================================================== // bfile.h #ifndef BFILE #define BFILE // These functions will demonstrate usage of constexpr ids in an extern unit extern void Baz(); extern void Qux(); #endif // BFILE //=================================================================== // bfile.cpp #include "afile.h" // Baz demonstrates that ids is (or works as) an extern field void Baz() { for (int i: ids) std::cout << i << ", "; std::cout << std::endl; } // Qux demonstrates that extern ids cannot work as constexpr, though void Qux() { #if 0 // changing me to non-0 gives you a compile-time error... Foo<ids[0]>(); #endif std::cout << "Qux: 'I don't see ids as consexpr, indeed.'" << std::endl; } //=================================================================== // main.cpp #include "afile.h" #include "bfile.h" int main(int , char **) { Bar(); Baz(); Qux(); return 0; }
Unable to compile crypto for SHA-256 hashing on Devc
#include <..\cryptopp\dll.h> #include <..\cryptopp\sha.h> #include <..\cryptopp\hex.h> #include<..\cryptopp\files.h> #include <iostream> #include<string> using namespace std; using namespace CryptoPP; const int MAX_PHRASE_LENGTH=250; int main(int argc, char *argv[]) { CryptoPP::SHA256 hash; byte digest[ CryptoPP::SHA256::DIGESTSIZE ]; std::string message = "Hello World!"; hash.CalculateDigest( digest, (const byte*)message.c_str(), message.length()); CryptoPP::HexEncoder encoder; std::string output; encoder.Attach( new CryptoPP::StringSink( output ) ); encoder.Put( digest, sizeof(digest) ); encoder.MessageEnd(); std::cout << "Input string: " << message << std::endl; std::cout << "SHA256: " << output << std::endl; return 0; } errors Compiler: Default compiler Executing g++.exe... g++.exe "C:\Users\Pr\Desktop\Work\encrypt\sha256\sampeSHA256.cpp" -o "C:\Users\Pr\Desktop\Work\encrypt\sha256\sampeSHA256.exe" -I"C:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include" -I"C:\Dev-Cpp\include\c++\3.4.2\backward" -I"C:\Dev-Cpp\include\c++\3.4.2\mingw32" -I"C:\Dev-Cpp\include\c++\3.4.2" -I"C:\Dev-Cpp\include" -L"C:\Dev-Cpp\lib" In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/seckey.h:8, from C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/rijndael.h:7, from C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/aes.h:4, from C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp\dll.h:11, from C:\Users\Pr\Desktop\Work\encrypt\sha256\sampeSHA256.cpp:1: C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/cryptlib.h:277: error: function std::string CryptoPP::NameValuePairs::GetValueNames() const' definition is marked dllimport. C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp\/cryptlib.h:283: error: functionbool CryptoPP::NameValuePairs::GetIntValue(const char*, int&) const' definition is marked dllimport. C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/cryptlib.h:287: error: function int CryptoPP::NameValuePairs::GetIntValueWithDefault(const char*, int) const' definition is marked dllimport. C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp\/cryptlib.h:291: error: functionstatic void CryptoPP::NameValuePairs::ThrowIfTypeMismatch(const char*, const std::type_info&, const std::type_info&)' definition is marked dllimport. C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/cryptlib.h:301: error: function `void CryptoPP::NameValuePairs::GetRequiredIntParameter(const char*, const char*, int&) const' definition is marked dllimport. In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/aes.h:4, from C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp\dll.h:11, from C:\Users\Pr\Desktop\Work\encrypt\sha256\sampeSHA256.cpp:1: C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/rijndael.h:15: error: function `static const char* CryptoPP::Rijndael_Info::StaticAlgorithmName()' definition is marked dllimport. In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp\dll.h:16, from C:\Users\Pr\Desktop\Work\encrypt\sha256\sampeSHA256.cpp:1: C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/des.h:58: error: function `static const char* CryptoPP::DES_EDE2_Info::StaticAlgorithmName()' definition is marked dllimport. C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/des.h:82: error: function `static const char* CryptoPP::DES_EDE3_Info::StaticAlgorithmName()' definition is marked dllimport. In file included from C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp\dll.h:37, from C:\Users\Pr\Desktop\Work\encrypt\sha256\sampeSHA256.cpp:1: C:/Dev-Cpp/include/c++/3.4.2/backward/..\cryptopp/skipjack.h:15: error: function `static const char* CryptoPP::SKIPJACK_Info::StaticAlgorithmName()' definition is marked dllimport. Execution terminated
Remove #include <..\cryptopp\dll.h> As Fraser said, use -L<path to Crypto++>. As Fraser said, use either -lcryptopp or -lcrypto++. The one you use depends on what you have. By default, its -lcryptopp.
undeclared identifier
Need a second set of eyes. I am getting the following error: 1>c:\users\thom\documents\cworkspace\barnaby\barnaby\timezone.h(15): error C2065: 'TransitionTimeInfo' : undeclared identifier Here is the line of code on which I'm receiving the error: Timezone(std::vector<LeapSecondsInfo> &leapSecondsVector, std::vector<unsigned char> &localTimeTypes, std::vector<P6::UINT8> &stdWallIndicators, &std::vector<unsigned long> &transitionTimes, std::vector<TransitionTimeInfo> &transitionTimesInfo, std::vector<P6::UINT8> &utcLocalIndicators){ This is the line for the constructor for my class. This file has the following include: #include "stdafx.h" And here is the salient part of the stdafx.h: #include "targetver.h" #include "barnaby.h" #include "LeapSecondsInfo.h" #include "p6types.h" #include "Timezone.h" #include "TransitionTimeInfo.h" And here is TransitionTimeInfo.h: class TransitionTimeInfo { public: TransitionTimeInfo(long gmtOffset, bool daylightSavings, unsigned int abbreviationIndex){ setAbbreviationIndex(abbreviationIndex); setDaylightSavings(daylightSavings); setGmtOffset(gmtOffset); } virtual ~TransitionTimeInfo(void) {}; unsigned int getAbbreviationIndex(){ return abbreviationIndex; } void setAbbreviationIndex(unsigned int newVal){ abbreviationIndex = newVal; } bool isDaylightSavings(){ return daylightSavings; } void setDaylightSavings(bool newVal){ daylightSavings = newVal; } long getGmtOffset(){ return gmtOffset; } void setGmtOffset(long newVal){ gmtOffset = newVal; } private: long gmtOffset; bool daylightSavings; unsigned int abbreviationIndex; }; What's more, if I click on the type name and hit F12 (Visual C++) it takes me to this file. Any ideas? Thanks.
Change the order of includes: #include "TransitionTimeInfo.h" #include "Timezone.h" The Timezone.h uses TransitionTimeInfo but the "TransitionTimeInfo.h" is included after it. Ideally, You should always follow the rule: Each file should include all the header files it needs and not rely on them getting included indirectly through some other files. So, You should include "TransitionTimeInfo.h" in "Timezone.h".