Can't build sigqueue example with gcc but g++ is ok? - c++

I have a strange build problem.
I have a simple test program that sends a sigqueue to another process.
This little code example builds and runs when I build it as a c++ program (compiled with g++)
but when I compile it as a c program (with gcc) I get a error that he can't find the sigval struct.
The short example:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
sigval value;
value.sival_int = 123;
sigqueue(0,SIGUSR1, value);
}
Please note that I replaced the pid with 0 to simplify this question.
And if I compile with gcc I get this:
$> gcc sigusr1_mini.c
sigusr1_mini.c: In function ‘main’:
sigusr1_mini.c:9: error: ‘sigval’ undeclared (first use in this function)
sigusr1_mini.c:9: error: (Each undeclared identifier is reported only once
sigusr1_mini.c:9: error: for each function it appears in.)
sigusr1_mini.c:9: error: expected ‘;’ before ‘value’
sigusr1_mini.c:10: error: ‘value’ undeclared (first use in this function)
What am I missing here, why can't he find the sigval struct?
And why can g++ find it?
Thanks
Johan

In C, struct and union tags do not introduce names that can be used on their own like they do in C++. You must spell it out:
union sigval value;

How is sigval defined in h-file? C compiler may require full definition, for example:
union sigval value;

Related

std::byte is not member of 'std'

I'm trying to learn new features/gimmicks of c++17, but then I got to std::byte and for some unknown reason I can't seem to be able to compile even most basic "hello world" type program with the type.
entire program:
#include <cstddef>
int main(int argc, char* argv[])
{
std::byte byte;
return 0;
}
compilation command:
g++ ./main.cpp
But the output is always:
./main.cpp: In function ‘int main(int, char**)’:
./main.cpp:4:10: error: ‘byte’ is not a member of ‘std’
std::byte byte;
I work on Ubuntu 18.04 with gcc 7.4.0. I have checked "/usr/include/c++/7.4.0/" and header file cstddef is there and byte seems to be defined.
I have also tried to use clang:
clang++ ./main.cpp
But the result was same. At this point I can only think that cstddef is corrupted/bugged. Are there any solutions to this?
As πάντα ῥεῖ pointed out in comment I was missing c++17 compile flag. Right compilation command:
g++ -std=c++17 ./main.cpp
If you use clang 5.0 (even with -std=c++17 flag) the same error occur.
In that case, to solve this you need to upgrade to clang 6.
A temporay and quick workaround is possible (but not recommanded since it plays with std namespace), it could be something like:
#if defined(__clang__) && __cplusplus >= 201703L && __clang_major__ < 6
// This is a minimal workaround for clang 5.0 with missing std::byte type
namespace std {
enum class byte : unsigned char {};
}
#endif

Typedef not a member of namespace

So, I'm attempting to fork some open source code and upon compilation I am greeted with these errors:
C2039 'TransactionId': is not a member of 'CryptoNote'
C2061 syntax error: identifier 'TransactionId'
I'm relatively inexperienced with C++ usually confining myself to the realms of C#, however, I can clearly see that TransactionId is a typedef declared in a different file like so:
namespace CryptoNote {
typedef size_t TransactionId;
typedef size_t TransferId;
//more code
And the line throwing the error is:
void sendTransactionCompleted(CryptoNote::TransactionId _id, bool _error, const QString& _error_text);
To my inexperienced eyes, that looks as though TransactionID is definitly a member of Cryptonote is it not?
Any ideas what's going on?
The repo is here: https://github.com/hughesjs/Incendium_GUI
And the necessary submodule is here: https://github.com/hughesjs/Incendium_Crypt
Those typedefs are defined in Incendium_Crypt/include/IWalletLegacy.h.
void sendTransactionCompleted(CryptoNote::TransactionId _id, bool _error, const QString& _error_text);`
is defined in Incendium_GUI/src/gui/SendFrame.h, which includes IWallet.h. However, IWallet.h does not in turn include IWalletLegacy.h. Hence, those typedefs are unknown to SendFrame.h.
It's difficult to say without seeing all the code but a few things come to mind:
Firstly is this the first error you get. Compilation errors with C++ tend to result in a bunch of secondary errors. For example the following results in a similar error to what you see but fails to compile because size_t has not been defined:
namespace CryptoNote {
typedef size_t TransactionId;
typedef size_t TransferId;
}
int main(void)
{
CryptoNote::TransactionId id;
return 0;
}
$ g++ -std=c++11 namespace.cxx -o namespace
namespace.cxx:4:9: error: ‘size_t’ does not name a type
typedef size_t TransactionId;
^~~~~~
namespace.cxx:5:9: error: ‘size_t’ does not name a type
typedef size_t TransferId;
^~~~~~
namespace.cxx: In function ‘int main()’:
namespace.cxx:11:17: error: ‘TransactionId’ is not a member of ‘CryptoNote’
CryptoNote::TransactionId id;
^~~~~~~~~~~~~
See http://www.cplusplus.com/reference/cstring/size_t/ for a list of headers that define size_t.
Is CryptoNote nested inside another namespace?
Is there another CryptoNote defined in the namespace your function is declared in?
Are these in the same header file? If not, is the header file where the namespace is defined included in the header file containing the function declaration?

Algorithm header llrint, llround compiler error

I'm learning C++ and I'm at the point of using the <algorithm> header and I get this compiler error even with an empty project:
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1108:11: error: '::llrint' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1109:11: error: '::llrintf' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1110:11: error: '::llrintl' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1112:11: error: '::llround' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1113:11: error: '::llroundf' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1114:11: error: '::llroundl' has not been declared
make: *** [algorithm.o] Error 1
Here is the code:
#include <iostream>
#include <algorithm>
using namespace std;
int main( int argc, char ** argv ){
return 0;
}
I'm using Eclipse with GCC 4.7.1 compiler and it's quite strange since the course I'm following is using Eclipse with Gcc 4.7 and it works.
Thanks

Is there any static checking tool to check buggy code like this

I wrote the some buggy code like this:
#include "stdafx.h"
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string some_file = "afdfadf";
if(true)
{
string some_file = "/"+ some_file;
}
return 0;
}
It will throw an exception when calling std::operator+.
I guess this is because in the if statement the second some_file is an uninitialized string.
Is there any static checking tool that can help find this kind of bug?
I just tried, clang can help find the bug:
[~]$ clang bug.cpp
bug.cpp:11:29: warning: variable 'some_file' is uninitialized when used within
its own initialization [-Wuninitialized]
string some_file = "/"+ some_file;
~~~~~~~~~ ^~~~~~~~~
GCC has a warning for that case:
$ g++ t.cc -Wshadow
t.cc: In function ‘int main(int, char**)’:
t.cc:11:16: warning: declaration of ‘some_file’ shadows a previous local [-Wshadow]
t.cc:7:12: warning: shadowed declaration is here [-Wshadow]
Compilers can warn you about using a variable in its own initialization.
In GCC and CLANG, you can use -Winit-self
I am not sure about MSVC, but compiling with /W4 might give you a warning about those, too.
I was quit happy with using pclint. It will find this type of errors but it might take some time to configure it when used with an existing, larger code base.

Compile error using boost::concept_check

I'm trying to compile simple example to use the boost concept_check
Code is as follow:
#include <vector>
#include <complex>
#include <algorithm>
#include <boost/iterator.hpp>
#include <boost/concept_check.hpp>
template <class foo>
void my_do_sort(std::vector<foo>& v)
{
BOOST_CONCEPT_ASSERT((RandomAccessIterator<foo>));
std::stable_sort(v.begin(),v.end())
}
int main()
{
std::vector<std::complex<double> > v;
v.push_back(std::complex<double>(1,3));
v.push_back(std::complex<double>(2,4));
my_do_sort(v);
}
I then get the following error:
g++ -I~/tmp/BOOST/boost_1_39_0 -g3 -ggdb -pedantic -pedantic-errors -Wall -Werror -O0 --save-temps con1.cpp -o con1
con1.cpp: In function 'void my_do_sort(std::vector<foo, std::allocator<_CharT> >&)':
con1.cpp:11: error: `*' cannot appear in a constant-expression
con1.cpp:11: error: a call to a constructor cannot appear in a constant-expression
con1.cpp:11: error: template argument 1 is invalid
con1.cpp:11: error: template argument 1 is invalid
con1.cpp:11: error: invalid type in declaration before ';' token
make: *** [con1] Error 1
Thanks
If you re-read your code, this shouldn't be surprising. It fails to compile because the concept check fails. You are asserting that foo should implement the RandomAccessIterator concept. The entire point in the library is to produce a compile error (just like the one you're seeing) if the concept check fails.
But foo is not an iterator. it is a std::complex<double>.
It should be BOOST_CONCEPT_ASSERT((RandomAccessIterator<v::iterator>)); as far as I can see.
You want to check that the vector iterator is a random access iterator. Not that the complex numbers stored in the iterator are random access iterators.
This was just compilation issue. I had to use boost namespace.