Suppress warning "expression result unused" on a index_sequence - attributes

This question is inspired by this answer.
The following code produces a warning of an unused value:
#include <array>
#include <vector>
#include <iostream>
#include <utility>
template <size_t... I>
auto f(std::index_sequence<I...>)
{
std::array<std::vector<int>, sizeof...(I)> res{(I, std::vector<int>(3, -1))...};
return res;
}
int main()
{
auto v = f(std::make_index_sequence<2>{});
for (const auto& vec : v)
{
for (const auto& x : vec)
std::cout << x << ' ';
std::cout << '\n';
}
return 0;
}
See it live on Coliru.
With gcc 10.1.0 the warning is
main.cpp:9:52: warning: left operand of comma operator has no effect [-Wunused-value]
9 | std::array<std::vector<int>, sizeof...(I)> res{(I, std::vector<int>(3, -1))...};
| ~~^~~~~~~~~~~~~~~~~~~~~~~~~~
with clang 10.0.1 the warning is
main.cpp:9:51: warning: expression result unused [-Wunused-value]
std::array<std::vector<int>, sizeof...(I)> res{(I, std::vector<int>(3, -1))...};
(and some similar ones).
In c++17 the attribute [[maybe_unused]] should allow to suppress warnings on unused variables. However, putting [[maybe_unused]] before the argument of f
auto f([[maybe_unused]] std::index_sequence<I...>)
has no effect.
How can one suppress the above warning?

You can cast I to void to discard the expression, and with it, the warning:
std::array<std::vector<int>, sizeof...(I)> res{
(static_cast<void>(I), std::vector<int>(3, -1))...
};

Related

cpp thread detach position?

my simple test code here:
// t.cpp
#include <iostream>
#include <chrono>
#include <thread>
void fcn()
{
uint8_t i = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout<<"hihi" << float(i++)<<std::endl;
}
}
std::thread t(fcn);
t.detach(); // detach position A
int main()
{
// t.detach(); // detach position B
uint8_t i = 0;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout<<"yoyo" << float(i++)<<std::endl;
}
}
compile and run by g++ ./t.cpp -o t -lpthread; ./t;
when detach at position A got compile error error: ‘t’ does not name a type | t.detach();,
but detach at position B is ok.
why is this different?
my situation is that i wish to move the fcn() and std::thread t(fcn) as well as t.detach() into a standalone header file later (for a better orginazation of the project) thanks

C++ portability from Windows to Linux

I have been successfully using the following code in C++ on Windows (via CodeBlocks) and have recently attempted to use the same code on Linux (Ubuntu 18.04) also via CodeBlocks. The code appears to compile fine but fails on execution.
The purpose of the code is to import a comma delimited text file of numbers into an array.
In both Windows and Linux I am using the GNU GCC Compiler.
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <cstdio>
#include <stdlib.h>
using namespace std;
typedef vector <double> record_t;
typedef vector <record_t> data_t;
istream& operator >> ( istream& ins, record_t& record)
{
record.clear();
string line;
getline( ins, line );
stringstream ss( line );
string field;
while (getline( ss, field, ',' ))
{
stringstream fs( field );
double f = 0.0;
fs >> f;
record.push_back( f );
}
return ins;
}
//-----------------------------------------------------------------------------
istream& operator >> ( istream& ins, data_t& data )
{
data.clear();
record_t record;
while (ins >> record)
{
data.push_back( record );
}
return ins;
}
//-----------------------------------------------------------------------------
int main()
{
data_t data;
ifstream infile( "Import File.txt" );
infile >> data;
if (!infile.eof())
{
cout << "Unsuccessful Import!\n";
return 1;
}
infile.close();
cout << "Your file contains " << data.size()-1 << " records.\n";
return 0;
}
I've checked that the necessary header files exist on Linux and that appears to be the case.
If I comment out the EOF check the console returns the message that
Process returned 49 (0x31)
A snippet of the import file which fails under Linux is:
1138,1139,1137.25,1138.5
1138.25,1138.75,1138.25,1138.5
1138.75,1139,1138.5,1138.75
1138.75,1138.75,1138.25,1138.25
1138.25,1138.25,1137.5,1137.5
1137.5,1138.75,1137.5,1138.5
1138.75,1143.75,1138.75,1143
1143.25,1145.75,1143.25,1144.5
1144.5,1144.75,1143,1143.25
1143.5,1144.5,1143.25,1144.25
Grateful for any help in finding a solution.
That return 4321; in main reports an unsuccessful return code to the OS. Only 0 return code (aka EXIT_SUCCESS) is considered successful.
Change it to return 0 or completely remove that return statement (in C++ main has implicit return 0).

Issue in predicate function in wait in thread C++

I am trying to put the condition inside a function but it is throwing confusing compile time error . While if I write it in lambda function like this []{ retur i == k;} it is showing k is unidentified . Can anybody tell How to solve this problem .
#include <iostream>
#include <mutex>
#include <sstream>
#include <thread>
#include <chrono>
#include <condition_variable>
using namespace std;
condition_variable cv;
mutex m;
int i;
bool check_func(int i,int k)
{
return i == k;
}
void print(int k)
{
unique_lock<mutex> lk(m);
cv.wait(lk,check_func(i,k)); // Line 33
cout<<"Thread no. "<<this_thread::get_id()<<" parameter "<<k<<"\n";
i++;
return;
}
int main()
{
thread threads[10];
for(int i = 0; i < 10; i++)
threads[i] = thread(print,i);
for(auto &t : threads)
t.join();
return 0;
}
Compiler Error:
In file included from 6:0:
/usr/include/c++/4.9/condition_variable: In instantiation of 'void std::condition_variable::wait(std::unique_lock<std::mutex>&, _Predicate) [with _Predicate = bool]':
33:30: required from here
/usr/include/c++/4.9/condition_variable:97:14: error: '__p' cannot be used as a function
while (!__p())
^
wait() takes a predicate, which is a callable unary function returning bool. wait() uses that predicate like so:
while (!pred()) {
wait(lock);
}
check_func(i,k) is a bool. It's not callable and it's a constant - which defeats the purpose. You're waiting on something that can change. You need to wrap it in something that can be repeatedly callable - like a lambda:
cv.wait(lk, [&]{ return check_func(i,k); });

Trouble with garbage chars in visual c++ file reading

I am trying to read a text file using the following code:
void function readfile(char *inputfile) {
istream is;
int filesize = 0;
is.open(inputfile);
if (!is.is_open()) {
return;
}
is.seekg(0, ios::end);
filesize = (int)is.tellg();
is.seekg(0, ios::beg);
char *buf = new char[filesize];
is.read(buf, filesize);
is.close();
cout << buf << endl;
delete[] buf;
return;
}
While in g++ (mac / macports) it works correctly (getting all contents into a dynamic allocated char* array), in Visual Studio C++ 2010, I get constant errors of this type: Debug assertion failed: (unsigned)(c+1) <= 256, file isctype.c.
The problem is that it opens the file but can't find a termination delimeter so when it reaches the eof it starts reading somewhere else (garbage characters). Using the cout << buf; I can see that the file is being read correctly in mac but in visual c++ it types more garbage chars. What is the problem here?
Make your buffer one larger and add the terminating nul yourself.
Let C++ standard library do the work for you:
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::string buf(std::istreambuf_iterator<char>(is), {});
std::cout << buf << std::endl;
}
See, it's now also
exception safe
handles embedded NUL characters correctly
Note, of course you can use vector instead of string if you prefer (just change that one word)
Full demo: see it live on Coliru
#include <fstream>
#include <iostream>
#include <iterator>
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::string buf(std::istreambuf_iterator<char>(is), {});
std::cout << buf << std::endl;
}
int main()
{
readfile("main.cpp");
}
Update For C++11 challenged compilers (and showing how to use a vector):
Also Live on Coliru
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::istreambuf_iterator<char> f(is), l;
std::vector<char> buf(f, l);
std::cout.write(buf.data(), buf.size());
}
int main()
{
readfile("main.cpp");
}

How to use boost.spirit.qi parse string value to attrubute with attribute has default value

I have a question for boost.spirit.qi string parser. When I want parse string value to std::string attribute, like bellow:
#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
template <typename P, typename T>
void test_phrase_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::ascii::space;
char const* f(input);
char const* l(f + strlen(f));
if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
int main()
{
std::string str("abc");
test_phrase_parser_attr("cba", string("cba"), str);
std::cout << str << std::endl;
return 0;
}
The output:abccba
But I want the program output "cba", How can I do?
Note that your str was initialized with "abc". Parser does not clear the string, just appends its output.
Pass in an empty string and you will get back what you want.

Resources