I am learning C++ right now and i get this somewhat weird error.
The Code is as follows:
#include <iostream>
#include <array>
using std::cout;
using std::endl;
using std::ostream;
using std::array;
template <typename T, size_t dim>
ostream& operator<<(ostream& os, const array<T,dim>& a) {
os << "[ ";
for (auto n : a)
os << n << " ";
os << "]";
return os;
}
int main()
{
cout << endl << "--- " << __FILE__ << " ---" << endl << endl;
array<int,3> a1 { 2,3,5 }; // (A)
array<int,0> a2 { }; // (B)
array<int,2> a3 { 1 }; // (C)
// array<int> x1 { 1, 2, 3 }; // (D)
// array<int,3> x2 { 1,2,3,4 };
array<int,3> a4 = { 1,2,3 }; // (E)
array<int,3> a5 { { 4,5,6 } }; // (F)
cout << "01| a1=" << a1 << endl;
cout << "02| a2=" << a2 << endl;
cout << "03| a3=" << a3 << endl;
cout << "04| a4=" << a4 << endl;
cout << "05| a5=" << a5 << endl;
cout << endl << "--- " << __FILE__ << " ---" << endl << endl;
return 0;
}
My IDE (Visual Studio Code) shows me the error, although the code is compiling and working.
Here is the makefile provided by our Prof.
# compiler settings
CXX = g++-7
# CXX = clang++
CXXFLAGS = -ansi -pedantic -Wall -Wextra -Wconversion -pthread -std=c++17
LDFLAGS = -lm
# collect files
CXXEXAMPLES = $(shell find . -name '*.cpp' -print -type f)
CXXTARGETS = $(foreach file, $(CXXEXAMPLES), ./out/$(file:.cpp=.out))
# build them all
all: $(CXXTARGETS)
out/%.out: %.cpp
$(CXX) $(CXXFLAGS) $< $(LDFLAGS) -o $#
clean:
rm out/*
I use Ubuntu 16.04 and thought it might be a compiler problem, so I changed "CXX" to "CXX = g++-7", because we were recommended to use g++ Version 7 but it didn't helped.
On typing "g++ -v" it shows that my gcc is version 5.5.0, but typing "apt list -installed" shows that g++-7 is installed.
I did not find any solution on the internet as most similar problems often revolved around missing includes.
VS Code also does not recognize some types of variable definitions like
"int n{1}"
It also complains about the "use of undeclared identifier" on the lines (A) to (E)
I assume the problem lies within the VS Code compiler using a different/old syntax recognition. But I don't know how to change that.
Related
I want to do:
int a = 255;
cout << a;
and have it show FF in the output, how would I do this?
Use:
#include <iostream>
...
std::cout << std::hex << a;
There are many other options to control the exact formatting of the output number, such as leading zeros and upper/lower case.
To manipulate the stream to print in hexadecimal use the hex manipulator:
cout << hex << a;
By default the hexadecimal characters are output in lowercase. To change it to uppercase use the uppercase manipulator:
cout << hex << uppercase << a;
To later change the output back to lowercase, use the nouppercase manipulator:
cout << nouppercase << b;
std::hex is defined in <ios> which is included by <iostream>. But to use things like std::setprecision/std::setw/std::setfill/etc you have to include <iomanip>.
If you want to print a single hex number, and then revert back to decimal you can use this:
std::cout << std::hex << num << std::dec << std::endl;
I understand this isn't what OP asked for, but I still think it is worth to point out how to do it with printf. I almost always prefer using it over std::cout (even with no previous C background).
printf("%.2X", a);
'2' defines the precision, 'X' or 'x' defines case.
std::hex gets you the hex formatting, but it is a stateful option, meaning you need to save and restore state or it will impact all future output.
Naively switching back to std::dec is only good if that's where the flags were before, which may not be the case, particularly if you're writing a library.
#include <iostream>
#include <ios>
...
std::ios_base::fmtflags f( cout.flags() ); // save flags state
std::cout << std::hex << a;
cout.flags( f ); // restore flags state
This combines Greg Hewgill's answer and info from another question.
There are different kinds of flags & masks you can use as well. Please refer http://www.cplusplus.com/reference/iostream/ios_base/setf/ for more information.
#include <iostream>
using namespace std;
int main()
{
int num = 255;
cout.setf(ios::hex, ios::basefield);
cout << "Hex: " << num << endl;
cout.unsetf(ios::hex);
cout << "Original format: " << num << endl;
return 0;
}
Use std::uppercase and std::hex to format integer variable a to be displayed in hexadecimal format.
#include <iostream>
int main() {
int a = 255;
// Formatting Integer
std::cout << std::uppercase << std::hex << a << std::endl; // Output: FF
std::cout << std::showbase << std::hex << a << std::endl; // Output: 0XFF
std::cout << std::nouppercase << std::showbase << std::hex << a << std::endl; // Output: 0xff
return 0;
}
C++20 std::format
This is now the cleanest method in my opinion, as it does not pollute std::cout state with std::hex:
main.cpp
#include <format>
#include <string>
int main() {
std::cout << std::format("{:x} {:#x} {}\n", 16, 17, 18);
}
Expected output:
10 0x11 18
Not yet implemented on GCC 10.0.1, Ubuntu 20.04.
But the awesome library that became C++20 and should be the same worked once installed on Ubuntu 22.04 with:
sudo apt install libfmt-dev
or:
git clone https://github.com/fmtlib/fmt
cd fmt
git checkout 061e364b25b5e5ca7cf50dd25282892922375ddc
mkdir build
cmake ..
sudo make install
main2.cpp
#include <fmt/core.h>
#include <iostream>
int main() {
std::cout << fmt::format("{:x} {:#x} {}\n", 16, 17, 18);
}
Compile and run:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main2.out main2.cpp -lfmt
./main2.out
Documented at:
https://en.cppreference.com/w/cpp/utility/format/format
https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification
More info at: std::string formatting like sprintf
Pre-C++20: cleanly print and restore std::cout to previous state
main.cpp
#include <iostream>
#include <string>
int main() {
std::ios oldState(nullptr);
oldState.copyfmt(std::cout);
std::cout << std::hex;
std::cout << 16 << std::endl;
std::cout.copyfmt(oldState);
std::cout << 17 << std::endl;
}
Compile and run:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
Output:
10
17
More details: Restore the state of std::cout after manipulating it
Tested on GCC 10.0.1, Ubuntu 20.04.
How are you!
#include <iostream>
#include <iomanip>
unsigned char arr[] = {4, 85, 250, 206};
for (const auto & elem : arr) {
std::cout << std::setfill('0')
<< std::setw(2)
<< std::uppercase
<< std::hex
<< (0xFF & elem)
<< " ";
}
I am trying to create (using C++17) a simple debug header that only executes some lines of code if the flag LOGGER_DEBUG_MODE is enabled. This is how my header is defined (I also tried using { x; } instead of x but the warning persists):
debug.h
#ifndef _HDEBUG
#define _HDEBUG
static bool LOGGER_DEBUG_MODE = true;
#define R_DEBUG(x) if(LOGGER_DEBUG_MODE == true) x
#endif
I included debug.h and at some point of my code I call the macro function R_DEBUG to print some values:
logger_adc.cpp
double anlg_device_t::eval_formula()
{
double result = -9999;
try
{
result = parser.Eval();
}
catch (mu::Parser::exception_type &e)
{
std::cout << e.GetMsg() << std::endl;
}
R_DEBUG(std::cout << "Eval Result: " << result << std::endl);
return result;
}
I expected everything to work properly but when I run the makefile I got this warning:
inc/debug.h:5:14: warning: 'LOGGER_DEBUG_MODE' defined but not used [-Wunused-variable]
static bool LOGGER_DEBUG_MODE = true;
I thought that my definition was messed up but after checking the temporary files created by g++, it appears that the preprocessor did everything as I expected:
logger_adc.ii
double anlg_device_t::eval_formula()
{
double result = -9999;
try
{
result = parser.Eval();
}
catch (mu::Parser::exception_type &e)
{
std::cout << e.GetMsg() << std::endl;
}
if(LOGGER_DEBUG_MODE == true) std::cout << "Eval Result: " << result << std::endl;
return result;
}
Why do I get the warning message even when the variable LOGGER_DEBUG_MODE is clearly being used inside the if statement? Did I mess up something obvious that I'm not picking up? My compile flags for the object files (where the warning occurs) are g++ -Wall -Wextra -O1 -g -std=c++17 -save-temps=obj -Iinc -I/usr/local/include -c plus pkg-config --cflags --libs libmodbus
If needed, this is my main function:
main.cpp
#include "logger_adc.h"
int main()
{
anlg_device_t test (ADC_CHIP_1, 1, 18, 1, 1, true);
test.set_formula("2*x","x", test.get_voltage_ptr());
std::cout << "Test Voltage: " << test.get_voltage() << std::endl << "Test Relative: " << test.get_relative() << std::endl;
std::cout << "Test Formula (2*x): " << test.eval_formula() << std::endl;
return 0;
}
Thanks in advance!
You have a header that defines a static bool LOGGER_DEBUG_MODE =true;. If you include that header in multiple C++ files then each file will gets its own copy of that bool.
In your main.cpp you aren't using R_DEBUG so the copy of that bool (which presumably comes from including logger_adc.h ) is indeed unused in that file.
Possible solutions are:
You should make it so you only have a single copy of that bool (declare it in the header with extern and define it in a single C++ file.
Use build defines instead of runtime checks
etc
I'm trying to use the filesystem library and it's not working I need help about compiling this.
I tried to change the included file and I updated my compiler but nothing works
here are the inclusions I made
#include <experimental/filesystem>
namespace fs = std::filesystem;
I compile the cpp file with this command
g++ -Wall -c indexation_fichier.cpp
I get this error
indexation_fichier.cpp:5:10: fatal error: experimental/filesystem: No such file or directory
#include <experimental/filesystem>
^~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
and here is my compiler version
g++ (MinGW.org GCC-8.2.0-1) 8.2.0
when I type
g++ --version
I want to know what is wrong and what I need to do to make this library work because I need it for my project.
thanks.
You can either compile your code using -lstdc++fs flag OR like #pete mentioned in the comment: remove experimental, as it is now part of standard C++17.
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
int main(){
fs::path pathToShow(fs::current_path());
std::cout << "exists() = " << fs::exists(pathToShow) << "\n"
<< "root_name() = " << pathToShow.root_name() << "\n"
<< "root_path() = " << pathToShow.root_path() << "\n"
<< "relative_path() = " << pathToShow.relative_path() << "\n"
<< "parent_path() = " << pathToShow.parent_path() << "\n"
<< "filename() = " << pathToShow.filename() << "\n"
<< "stem() = " << pathToShow.stem() << "\n"
<< "extension() = " << pathToShow.extension() << "\n";
return 0;
}
and then something like g++ -o fs filesystem.cpp will work fine.
solved
I had to delete the old object-files and rebuilt the whole project to fix the problem. Unfortunately I don't know the very reason why I got this error.
Maybe it where some wrong placed include-statements or there may have been definitions in the class declaration of accountsContainer.h which I had removed meanwhile.
I am trying to compile a little C/C++ application and am stuck with a linking problem:
the exact error is this:
make all
g++ -g -Wall -fmessage-length=0 -I "Z:/SRS/Verwaltung/EDV/Marcus EDV/Programmierung/link libraries/c++/curl-7.24.0/include/curl/" -c -o accountsContainer.o accountsContainer.cpp
g++ -o libcurl.exe signatureUpdater.o accountsContainer.o network.o registry.o emailAccount.o filesystem.o libcurl.o "Z:/SRS/Verwaltung/EDV/Marcus EDV/Programmierung/link libraries/c++/curl-7.24.0/lib/libcurl.dll"
accountsContainer.o: In function `accountsContainer':
G:\#1Arbeit\htdocs\libcurl/accountsContainer.cpp:11: multiple definition of `accountsContainer::accountsContainer()'
signatureUpdater.o:G:\#1Arbeit\htdocs\libcurl/accountsContainer.h:13: first defined here
collect2: ld returned 1 exit status
make: *** [libcurl.exe] Error 1
I don't understand where this error comes from. I already did some research on the internet for the "multiple definition of"-error.
This is what I know:
I think you can declare classes or functions several times as often as you want, but I must only be defined once.
And this is what I did:
I defined the class constructor "accountsContainer::accountsContainer(){...}" in the accountsContainer.cpp which is never included anywhere, but should only be compiled with my make-file to accountsContainer.o
accountsContainer.h contains the declaration of the class
But why does the linker complain about a definition of accountsContainer::accountsContainer(){...} in the header file?
These are my files:
"accountsContainer.h"
/*
* accountsContainer.h
*
* Created on: 16.03.2012
* Author: Admin
*/
#ifndef ACCOUNTSCONTAINER_H_
#define ACCOUNTSCONTAINER_H_
#include "emailAccount.h"
#include <string>
#include <iostream>
#include <algorithm>
class accountsContainer {
public:
const static int MAX_ACCOUNTS = 50;
private:
emailAccount srsAccounts[],emailAccounts[];
//can only be initalized in the constructor
int nAccounts;
int nSrsAccounts;
//methods
private:
void emailToLowerCase();
void findSrsAccounts();
public:
accountsContainer();
void printSrsAccounts();
emailAccount & getSrsAccount(int);
};
#endif /* ACCOUNTSCONTAINER_H_ */
"accountsContainer.cpp"
/*
* accountsContainer.cpp
*
* Created on: 16.03.2012
* Author: Admin
*/
#include "accountsContainer.h"
#include "signatureUpdater.h"
accountsContainer::accountsContainer() {
//init variables
nAccounts = 0;
nSrsAccounts = 0;
/*
* read email Accounts from registry and save them to the srsAccounts Array
*/
signatureUpdater::reg.getEmailAccounts(srsAccounts,MAX_ACCOUNTS);
//make all e-mail adresses lower case
emailToLowerCase();
findSrsAccounts();
}
void accountsContainer::printSrsAccounts(){
string locS;
for(int i=0;i < nSrsAccounts;i++){
wcout << L"Account " << i << L" : " << srsAccounts[i].displayName <<endl;
wcout << L"Name: " << srsAccounts[i].accName.c_str() << endl;
wcout << L"E-Mail:" << srsAccounts[i].email.c_str() << endl << endl;
}
}
emailAccount & accountsContainer::getSrsAccount(int i){
return srsAccounts[i];
}
void accountsContainer::emailToLowerCase(){
wstring s;
for(int i=0; i < nAccounts; i++){
s = emailAccounts[i].email;
std::transform(s.begin(), s.end(), s.begin(), std::ptr_fun<int,int>(std::tolower));
emailAccounts[i].email = s;
}
}
void accountsContainer::findSrsAccounts(){
/*
* resets Number of SRS accounts
* then iterates all e-mail accounts
* and searches for domain srsonline.de
* in lowercase!
*/
size_t found;
wstring emailAdr;
nSrsAccounts = 0;
for(int i=0;i<nAccounts;i++){
emailAdr=emailAccounts[i].email;
found = emailAdr.rfind(L"srsonline.de");
if(found != string::npos && (emailAdr.length()-found) == 12){
/*
wcout << L"für E-mail Konto: " << emailAdr << endl;
cout << "srsonline.de found at: " << found << endl;
*/
// copy SRS Accounts to srsAccounts array
srsAccounts[nSrsAccounts] = emailAccounts[i];
nSrsAccounts++;
}
}
}
and thats my makefile:
CXXFLAGS = -g -Wall -fmessage-length=0 -I "Z:/SRS/Verwaltung/EDV/Marcus EDV/Programmierung/link libraries/c++/curl-7.24.0/include/curl/" # -O2 no performance improvement because of debugging!
OBJS = signatureUpdater.o accountsContainer.o network.o registry.o emailAccount.o filesystem.o libcurl.o
LIBS = "Z:/SRS/Verwaltung/EDV/Marcus EDV/Programmierung/link libraries/c++/curl-7.24.0/lib/libcurl.dll"
TARGET = libcurl.exe
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
I hope that the problem doesn't come from a bad programm-architectur/design
thank you for your help!
Check the include guards, maybe you use the same name in another header.
I'm trying to store objects in a std::set. Those objects are boost::shared_ptr<>, coming from the python environment. adding values to the set won't cause any troubles. But when I try to erase a value, even though I'm passing the very same reference, it won't work. Here is an example :
#include <set>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/python.hpp>
using namespace std;
using namespace boost;
using namespace boost::python;
struct Bar
{
Bar() {}
};
struct Foo
{
set< shared_ptr<Bar> > v_set;
shared_ptr<Bar> v_ptr;
Foo() {}
void add( shared_ptr<Bar> v_param ) {
cout << "storing " << v_param << "in v_set and v_ptr" << endl;
v_set.insert(v_param);
v_ptr = v_param;
}
void del( shared_ptr<Bar> v_param ) {
cout << "deleting " << v_param << endl;
if (v_param == v_ptr) {
cout << "v_param == v_ptr" << endl;
} else {
cout << "v_param != v_ptr" << endl;
}
cout << "erasing from v_set using v_param" << endl;
if (v_set.erase(v_param) == 0) {
cout << "didn't erase anything" << endl;
} else {
cout << "erased !" << endl;
}
cout << "erasing from v_set using v_ptr" << endl;
if (v_set.erase(v_ptr) == 0) {
cout << "didn't erase anything" << endl;
} else {
cout << "erased !" << endl;
}
}
};
BOOST_PYTHON_MODULE (test)
{
class_< Foo, shared_ptr<Foo> >("Foo")
.def("add",&Foo::add)
.def("remove",&Foo::del);
class_< Bar, shared_ptr<Bar> >("Bar");
}
compiling :
%> gcc -pthread -fno-strict-aliasing -march=i686 -mtune=generic -O2 -pipe -DNDEBUG -march=i686 -mtune=generic -O2 -pipe -fPIC -I/usr/include/python2.7 -c test.cpp -o test.o
%> g++ -pthread -shared -Wl,--hash-style=gnu -Wl,--as-needed build/temp.linux-i686-2.7/test.o -L/usr/lib -lboost_python -lpython2.7 -o test.so
and now, a small python script :
from test import *
f = Foo()
b = Bar()
f.add(b)
f.remove(b)
Here is the result :
storing 0x8c8bc58in v_set and v_ptr
deleting 0x8c8bc58
v_param == v_ptr
erasing from v_set using v_param
didn't erase anything
erasing from v_set using v_ptr
erased !
I store 0x8e89c58 inside the set and outside, just in case
I'm passing the same reference to both calls (0x8e89c58)
just to make sure i check if v == val
I try to erase by using v -- it doesn't work
I try to erase by using val -- it works !
I'm completely lost there - can't see what is causing this. Any input ?
I ran your example then added some assertions that I thought should hold in del():
assert(!(v_param < v_ptr));
assert(!(v_ptr < v_param));
One of them failed!
I dug into the implementation of operator< for boost::shared_ptr and found something strange: it compares the reference counts rather than the internal pointers! A little digging found a mailing list post about this issue with some helpful links to two C++ documents: N1590 which explains why people thought this was a good idea, and N2637 which explains why it wasn't.
It seems that the Boost people have not (yet?) adopted the N2637 recommendation, but C++11 has. So I built your test again using C++11 (g++ -std=c++0x), having removed using namespace boost; so as to use std::shared_ptr. This resulted in a horrible template-ridden error message which was solved by adding this at the top (easily derived from boost/smart_ptr/shared_ptr.hpp):
template<class T> inline T * get_pointer(std::shared_ptr<T> const & p)
{
return p.get();
}
And it works!
If you can't use C++11, just implement your own custom comparator for your set which compares the pointers sanely:
template <typename T>
struct SmartComparator
{
bool operator()(shared_ptr<T> const& lhs, shared_ptr<T> const& rhs) {
return lhs.get() < rhs.get();
}
};
Then this will work:
set< shared_ptr<Bar>, SmartComparator<Bar> > v_set;