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(&notmain_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 &notmain_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".