Qt compile error: endl will always evaluate to true - c++

I have the following code snippet that compiles
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
for (QStringList::Iterator it = commandList.begin(); it != commandList.end(); ++it) {
out << "Command: " << *it << endl;
}
but always gives me this warning:
test.cpp:87: warning: the address of 'QTextStream& endl(QTextStream&)' will always evaluate as 'true' [-Waddress]
What does it mean and how do I fix it? Since a newline character is printing I assume this is not a namespace issue...

When you are using a binary data stream, it is not a good practice to start inserting new lines. That is one of the main points over a simple QTextStream.
This code works fine for me without any warning with gcc version 4.8.1 20130725 (prerelease) (GCC)
main.cpp
#include <QByteArray>
#include <QDataStream>
#include <QIODevice>
#include <QStringList>
int main()
{
QStringList commandList = QStringList() << "foo" << "bar" << "baz";
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
for (QStringList::Iterator it = commandList.begin(); it != commandList.end(); ++it)
out << "Command: " << *it;
}
Building
g++ -std=c++11 -Wpedantic -Wall -I/usr/include/qt -I/usr/include/qt/QtCore -lQt5Core -fPIC main.cpp

Related

C++ - Compile and link multiple files

I have a project with the following structure:
Item.cpp
Item.h
main.cpp
Makefile
The following source code is in the Item.h file:
class Item {
public:
Item();
~Item();
};
The following source code is in the Item.cpp file:
#include <iostream>
#include "Item.h"
Item::Item() {
std::cout << "Item created..." << std::endl;
}
Item::~Item() {
std::cout << "Item destroyed..." << std::endl;
}
The following source code is the content of the main.cpp file:
#include "Item.h"
#include <iostream>
int main() {
std::cout << "Initialize program..." << std::endl;
Item item_1();
std::cout << "Hello world!" << std::endl;
return 0;
}
And finally, the following source code is the Makefile file:
CXX = g++
all: main item
$(CXX) -o sales.o main.o Item.o
main:
$(CXX) -c main.cpp
item:
$(CXX) -c Item.cpp
clean:
rm -rf *.o
When I run the make command and then I run the compiled code with the command ./sales.o, I get the following output:
Initialize program...
Hello world!
Why is the output of the constructor method of the class Item not printed in the console? I found in some web pages that you can compile the source codes in steps and then you can link it with the -o option when using g++ but it does not work in this case. How can I compile this source codes step by step and then link it in the Makefile?
I'm surely you ignored this warning :
warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse]
#include "Item.h"
#include <iostream>
int main() {
std::cout << "Initialize program..." << std::endl;
Item item_1;
std::cout << "Hello world!" << std::endl;
return 0;
}
just remove parentheses it will be work
test : https://godbolt.org/z/KrdrhvsrW

Variable Not In Scope for Lambda

I'm trying to diagnose a timing issue on a multi-core processor [Xeon Silver]. I think that the clocks have not been configured or synced between the processor. I'm using Eli Bendersky's [credited in the code snippet] threading examples to build a test instrument. I have made three changes. I made made the sleep occur first, and I added a call to std::chrono::system_clock::now() and tried to print it out. I'm building with gcc 4.8.5 on CentOS 7.5.
The code is as follows:
// // Eli Bendersky [http://eli.thegreenplace.net]
// This code is in the public domain.
#include <algorithm>
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include <pthread.h>
int main(int argc, const char** argv) {
unsigned num_cpus = std::thread::hardware_concurrency();
std::cout << "Launching " << num_cpus << " threads\n";
// A mutex ensures orderly access to std::cout from multiple threads.
std::mutex iomutex;
std::vector<std::thread> threads(num_cpus);
for (unsigned i = 0; i < num_cpus; ++i)
{
threads[i] = std::thread([&iomutex, i]
{
// Simulate important work done by the tread by sleeping for a bit...
std::this_thread::sleep_for(std::chrono::milliseconds(200));
{
std::chrono::time_point ti = std::chrono::system_clock::now();
// Use a lexical scope and lock_guard to safely lock the mutex only for
// the duration of std::cout usage.
std::lock_guard<std::mutex> iolock(iomutex);
std::cout << "Thread #" << i << " hit its clock at: " << ti.time_since_epoch() << "\n";
}
});
}
for (auto& t : threads) {
t.join();
}
return 0;
}
I build with make:
CXX = g++
CXXFLAGS = -std=c++11 -Wall -O3 -g -DNDEBUG -pthread
LDFLAGS = -lpthread -pthread
clock-check: clock-check.cpp
$(CXX) $(CXXFLAGS) $^ -o $# $(LDFLAGS)
GCC gives me the following error:
[user#sbc1 concur]$ make clock-check
g++ -std=c++11 -Wall -O3 -g -DNDEBUG -pthread clock-check.cpp -o clock-check -lpthread -pthread
clock-check.cpp: In lambda function:
clock-check.cpp:32:67: error: ‘ti’ was not declared in this scope
std::cout << "Thread #" << i << " hit its clock at: " << ti.time_since_epoch() << "\n";
^
make: *** [clock-check] Error 1
ti is clearly in the same block scope as the print statement, and I'm baffled why the compiler is complaining. I have not found any restrictions on variables local to the lambda. Most of what I have found has been references to captures.
Your problem lies in this line:
std::chrono::time_point ti = std::chrono::system_clock::now();
std::chrono::time_point expect a type argument (e.g. std::chrono::time_point<std::chrono::system_clock>)
Prefer to use auto in this case:
auto ti = std::chrono::system_clock::now();
Then, you'll have an error since you try to output a std::chrono::duration in an output stream.
You should do:
std::cout << "Thread #" << i << " hit its clock at: " << ti.time_since_epoch().count() << "\n";
It seems to be a bug in older gcc versions. With gcc 10.1 (--std=c++11) I get the error:
<source>: In lambda function:
<source>:23:34: error: missing template arguments before 'ti'
23 | std::chrono::time_point ti = std::chrono::system_clock::now();
| ^~
<source>:27:67: error: 'ti' was not declared in this scope; did you mean 'i'?
27 | std::cout << "Thread #" << i << " hit its clock at: " << ti.time_since_epoch() << "\n";
| ^~
|
The error about the missing template parameter (which is missing with gcc 4.5.8) on the declaration explains the second error.
Strangely gcc 4.8.5 with -std=c++11 happily compiles the code if you remove the line with std::cout: https://godbolt.org/z/6LREHF
Class template deduction is not available until c++17, so you need to specify your template parameters for chrono::timepoint. Alternatively, use auto:
auto ti = std::chrono::system_clock::now();
Furthermore, you attempt to stream a chrono::duration type, which is not possible. Use ti.time_since_epoch().count().
Live example

C++: Armadillo does not want to cooperate with hdf5 format

Recently I have decided to store my data into hdf5 binary instead of ASCII files. I would like to use hdf5 format. Basically the thought is have the header and the data in the same file (header ASCII not binary format and then binary format). Something like this:
----------------------------------------
Dataname : testdata
ref_ell : wgs84
bmin :
etc.
and here are the data in hdf5 format
The armadillo library (http://arma.sourceforge.net/docs.html#save_load_mat) do have the function to append data to the existing file (hdf5_opts::append). But I have reached the problem much sooner. I have followed the manual but apparently I did something wrong. Lets say I have:
#include <iomanip>
#include <iostream>
#include <fstream>
#include <map>
#include <cmath>
#include <algorithm>
#include <vector>
#define ARMA_USE_HDF5
#include <hdf5.h>
#include <armadillo>
// g++ -O3 -lhdf5 -larmadillo -DARMA_DONT_USE_WRAPPER -DARMA_USE_BLAS -DARMA_USE_LAPACK -DARMA_USE_HDF5 - hdf5.cpp -o hdf5.o
// g++ -O3 -lhdf5 -larmadillo hdf5.cpp -o hdf5.o
// g++ -O3 -larmadillo -lhdf5 hdf5.cpp -o hdf5.o
using namespace std;
int main() {
arma::mat amat = arma::randu<arma::mat>(5,6);
cout << amat << endl;
amat.save( arma::hdf5_name("A.h5", "my_data"));
arma::mat bmat;
bool t = bmat.load( arma::hdf5_name("A.h5", "my_data"));
cout << bmat << endl;
if(t == false)
cout << "problem with loading" << endl;
return 0;
}
I tried to compile this exercise but I get only errors:
Either this:
hdf5.cpp: In function ‘int main()’:
hdf5.cpp:28:43: error: ‘hdf5_name’ was not declared in this scope
amat.save( hdf5_name("A.h5", "my_data"));
Or:
g++ -O3 -lhdf5 -larmadillo hdf5.cpp -o hdf5.o
hdf5.cpp: In function ‘int main()’:
hdf5.cpp:27:16: error: ‘hdf5_name’ is not a member of ‘arma’
amat.save( arma::hdf5_name("A.h5", "my_data"), arma::hdf5_binary);
What am I missing? (Solved - an update of the armadillo lib was required !)
Proceeding to second part of the problem: To save the header first and then add the data in hdf5 format. This way it works. But the header is added after the matrix is stored.
#include <iomanip>
#include <iostream>
#include <fstream>
#include <map>
#include <cmath>
#include <algorithm>
#include <vector>
#define ARMA_USE_HDF5
#define ARMA_DONT_USE_WRAPPER
#include <hdf5.h>
#include <armadillo>
// g++ -O3 -larmadillo -lhdf5 hdf5.cpp -o hdf5.o
using namespace std;
int main() {
arma::mat amat = arma::randu<arma::mat>(5,6);
cout << amat << endl;
amat.save( arma::hdf5_name("A.hdf5", "gmodel", arma::hdf5_opts::append ) );
ofstream f_out; f_out.open( "A.hdf5", ios::app );
f_out << "\nbegin_of_head ================================================\n";
f_out << "model name : " << "model_name" << endl;
f_out << "model type : " << "model_type" << endl;
f_out << "units : " << "units" << endl;
f_out << "ref_ell : " << "ref_ell" << endl;
f_out << "ISG format = " << "isg_format" << endl;;
f_out << "end_of_head ==================================================\n";
f_out.close();
return 0;
}
When i switch the order, the amat.save() function just rewrites the content of the A.hdf5 file.
For me the code worked (in Ubuntu 17.10) using
g++ hdf5.cpp `pkg-config --cflags --libs hdf5` -DARMA_DONT_USE_WRAPPER -I/home/claes/armadillo-8.500/include -o hdf5.o -lblas -llapack
where
`pkg-config --cflags --libs hdf5`
expands to
-I/usr/include/hdf5/serial -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5

openssl error "EVP_DigestInit_ex:initialization error" using EVP-library

I have a problem with openssl and the EVP-functions:
When I execute the following code
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <array>
#include <iostream>
void hash(ENGINE* eng) {
EVP_MD_CTX *_mdctx(EVP_MD_CTX_create());
int ret = EVP_DigestInit_ex(_mdctx, EVP_sha512(), eng);
EVP_MD_CTX_destroy(_mdctx);
if(1 == ret) {
std::cout << "Finished successfully (with eng=" << eng << ")" << std::endl;
return;
} else {
std::array<char, 256> err_str;
ERR_error_string_n(ERR_get_error(), err_str.data(), err_str.size());
std::cout << "Error at Digest (engine: " << ENGINE_get_id(eng) << "): " << err_str.data() << std::endl;
}
}
int main(void) {
ENGINE_load_builtin_engines();
hash(nullptr);
for(ENGINE *eng = ENGINE_get_first(); eng != nullptr; eng = ENGINE_get_next(eng)) {
hash(eng);
}
}
I get the following output:
Finished successfully (with eng=0)
Error at Digest (engine: rdrand): error:260BA093:engine routines:ENGINE_get_digest:unimplemented digest
Error at Digest (engine: dynamic): error:06080086:digital envelope routines:EVP_DigestInit_ex:initialization error
I understand, that rdrand doesn't support digest, but why do I get an initialization error, when I use the dynamic engine? In particular why does it work, when I call EVP_DigestInit_ex with eng=nullptr?
The code can be compiled with g++ example.cpp -std=c++17 -Wall -Wextra -Werror -pedantic -O2 -lssl -lcrypto. I am using g++, version 6.3.0 and openssl 1.1.0f.

C++ DevIL function ilLoadImage - program exit, access violation

I've got a path to my file defined this way:
const char* GROUND_TEXTURE_FILE = "objects/textures/grass.jpg";
And here is the function, which I use to load image:
bool loadTexImage2D(const string &fileName, GLenum target) {
...
// this will load image data to the currently bound image
// at first, we must convert fileName, for ascii, this method is fine?
wstring file(fileName.begin(), fileName.end());
if(ilLoadImage(file.c_str()) == IL_FALSE) { //here the program falls
What's wrong in my code? Why the program falls when ilLoadImage is called? I think, that file.c_str() should work fine as a wchar_t * type or not? Thanks for answer :)
As the author's said, you can do pretty anything without initializing the lib :D
#include <iostream>
#include <IL/il.h>
int main ()
{
std::string filename = "objects/textures/grass.jpg";
ilInit();
if (!ilLoadImage(filename.c_str())) {
std::cout << ilGetError() << std::endl;
return 1;
}
std::cout << ilGetInteger(IL_IMAGE_WIDTH) << std::endl;
std::cout << ilGetInteger(IL_IMAGE_HEIGHT) << std::endl;
return 0;
}
build:
g++ -Wall -pedantic --std=c++11 -g -o app main.cpp -lIL