when compiling a C++ program which contains a "call" to the pthread_cleanup_pop(E) macro, the following error is thrown by g++:
error: second operand to the conditional operator is of type 'void', but the third operand is neither a throw-expression nor of type 'void'
Now, the apparent problem here is that the macro above expands to
(*pthread_getclean() = _pthread_cup.next, (E?_pthread_cup.func((pthread_once_t *)_pthread_cup.arg):0));} where the second expression is a call to a function returning void, but the third expression is simply 0.
Althoug I get the basic issue here, I really don't see why the warning occurs in this particular use, as the "result" of the condition is not assigned to anything.
For the record: I compiled the C++ program using MinGW-w64 3.3.0 (GCC 4.9.2) both with and without -std=c++98. In both cases, the error occurs. If I compile the same code as a C program (both with or without -std=c99), there is no error.
Does anyone know how I could get rid of that error in C++, other than by editing pthread.h?
Many thanks in advance!
EDIT: Here is some example code for reference:
#include <pthread.h>
static int cancelled = 0;
static void test_thread_cleanup(void *_arg){
cancelled = 1;
}
static void* test_thread(void *_arg){
pthread_cleanup_push(&test_thread_cleanup, NULL); // push cleanup handler on stack
while (1){ // never left unless cancelled via pthread_cancel() from main()
pthread_testcancel(); // just test for pthread_cancel() having been called
}
pthread_cleanup_pop(1); // pop cleanup handler from stack
return NULL; // actually never reached
}
int main(void){
pthread_t th;
pthread_create(&th, NULL, &test_thread, NULL);
pthread_cancel(th);
pthread_join(th, NULL);
return cancelled;
}
Related
I found this situation in my recent project. I wanna ask if it is designed as so, what's the underlying mechanism, and how is it useful?
Although I know the subscript in parameters list is somehow useless to compiler, but in my situation, it might be better to raise an error and stop compile.
The source code:
#include <cstdio>
template<typename Type>
class A{
public:
// passes compile, although it is not declared
void print(int data[Type::len]) { // Line 7
printf("%d\n", data[0]);
}
// error: not declared
// void print(int data[dummy]) {
// printf("%d\n", data[0]);
// }
};
// error: not declared
// void print(int data[A<double>::len]) {
// printf("%d\n", data[0]);
// }
int main() {
A<int> a;
int x[12] = { 0 };
a.print(x); // Line 23
return 0;
}
Compile command using gcc 11.3.0:
g++ -o a a.cpp -Wall -Wextra
No compile output, program prints a "0" and exits with 0.
But in msvc 19.33.31630, it raises C2825, C2510 on line 7, and C2670 on line 23.
There should be an error and that there isn't one is a known bug in GCC.
If the array bound Type::len was valid, then the type int[Type::len] in the function parameter would be rewritten to int* in the instantiation, as is always the case for array types in function parameters. So the actual value of the array bound will not matter from there on out.
However, if Type::len is not a valid constant expression with a suitable value for an array bound, then substitution should fail and the program should be ill-formed. In case of T=int, Type::len is not a valid expression at all and so it should fail to compile (or at least issue some diagnostic). This should happen already at A<int> a; (which causes implicit instantiation of A<int> including A<int>::print's declaration), even if no actual call to print is present.
It seems GCC is performing the rewriting step too early without verifying that the expression in the array bound is actually valid in the substitution.
GCC has a meta-bug report with multiple linked individual bug reports related to this here.
I am trying to use C++17 if constexpr feature but fail to compile a simple function.
Code:
template <auto B>
int foo()
{
if constexpr(B)
{
return 1;
}
else
{
return 2;
}
} // <- I get an error here
int main()
{
return foo<false>();
}
The error output by compiler:
<source>(12): error #1011: missing return statement at end of non-void function "foo<B>() [with B=false]"
}
Used -std=c++17 -O3 -Wall -Werror compiler flags and icc 19.0.1 compiler.
Is this valid C++17 code?
What is the reason behind this error?
Is this valid C++17 code?
Yes, it's valid. Exactly one return statement will be discarded, while the other will remain. Even if none remain, C++ still allows you to omit a return statement from a function. You get undefined behavior if the function's closing curly brace is reached, but that's a risk only if execution reaches that point.
In your case, execution cannot reach such a point, so UB is not possible.
What is the reason behind this error?
You used -Werror, thus turning the compiler's false positive warning into a hard error. One workaround is to disable this warning around that particular function. This is purely a quality of implementation problem.
I am trying to call a function named characterSelection(SDL_Surface *screen, struct SelectionneNonSelectionne sel) which returns a void
This is the .h of the function I try to call:
struct SelectionneNonSelectionne;
void characterSelection(SDL_Surface *screen, struct SelectionneNonSelectionne);
void resetSelection(SDL_Surface *screen, struct SelectionneNonSelectionne);
On my main function, I try to call it like this:
characterSelection(screen, SelectionneNonSelectionne);
When I compile, I have the message:
error: expected primary-expression before ')' token
I made the includes. I suppose I miscall the second argument, my struct. But, I can't find why on the net.
Have you got any idea about what I did wrong?
You should create a variable of the type SelectionneNonSelectionne.
struct SelectionneNonSelectionne var;
After that pass that variable to the function like
characterSelection(screen, var);
The error is caused since you are passing the type name SelectionneNonSelectionne
A function call needs to be performed with objects. You are doing the equivalent of this:
// function declaration/definition
void foo(int) {}
// function call
foo(int); // wat!??
i.e. passing a type where an object is required. This makes no sense in C or C++. You need to be doing
int i = 42;
foo(i);
or
foo(42);
You're passing a type as an argument, not an object. You need to do characterSelection(screen, test); where test is of type SelectionneNonSelectionne.
I seen this problem with the latest nightly build of Code::Blocks. When I switched back to the stable release of Code::Blocks, 20.03 at the time of this writing, the problem went away and my code compiled and ran without problems. I'm not sure what Code::Blocks is doing, but it is very annoying. I got this repeatedly on a C++ project for every NULL in my code, forcing me to use nullptr instead.
EDIT
Still don't know what the problem is. Seemed allot like I had multiple files, but sure I didn't. Anyway, I renamed my class .h and .cc filed, and renamed the classes themselves. Didn't actually change any code, but now the problem is gone.
I would like to get rid of this question as I cant see it helping anyone in the future. Obviously was a local mistake of mine.
I am calling a method from my main function and using the boolean return in an if statement. The method is declared as a bool return, but the compiler seems to think its a void return. I've tried changing to bool to int and changing the if evaluation, but the compiler still seems to think its a void function. I have no idea what's wrong.
method deceleration inside class definition (as public)
bool check_online();
method definition inside class cc file
bool Icarus::check_online()
{
char ret = 0x00;
//check if bluetooth adapter exists
if(! input)
{
mvwaddstr(feedback,1,1,"COULD NOT OPEN rfcomm0 FOR SERVICE");
wrefresh(feedback);
getch();
return(0);
}
//check if Daedalus is online
if(send_cr())
{
mvwaddstr(feedback,1,1,"Daedalus is Online ");
wrefresh(feedback);
return(1);
}
else
{
mvwaddstr(feedback,1,1,"Daedalus is Offline ");
wrefresh(feedback);
return(0);
}
}
calling the method in main.
if(driver.check_online() == false)
{
getch();
cleanup();
}
resulting error
$ g++ -g icarus.cc main.cc -o icarus -lncurses -lpthread
main.cc: In function ‘int main()’:
main.cc:34:30: error: invalid operands of types ‘void’ and ‘bool’ to binary ‘operator==’
I understand what the compiler error means, but I dont understand why its being thrown up. The function is clearly a bool return. Any help?
I am trying to take a list data type I created and make it a template. In doing so I've run into the following obscure problem. I can post all of the code if needed, but this is really the function that is causing the problem.
Note: This code was compiling just fine until I got to this method. I was compiling after writing every few lines as a sanity check, and everything was fine, but then I get to this point and it blows up. If I take the try/catch block out of this method it compiles just fine, so I'm pretty sure the problem is isolated there, not a missing semicolon in a header/etc. as reported from other answers -- though I did of course triple-check to be sure! :)
Here's the code that is causing the problem:
template<class T>
bool UnsortedListType<T>::IsFull()
{
try { return false; }
catch(std::bad_alloc exception) { return true; } // line 35
}
Like I said, I simplified it as much as possible while still triggering the error. Here is the error:
UnsortedListType.cpp||In member function 'bool UnsortedListType<T>::IsFull()':
UnsortedListType.cpp|35|error: expected type-specifier
UnsortedListType.cpp|35|error: expected unqualified-id before 'exception'
UnsortedListType.cpp|35|error: expected ')' before 'exception'
UnsortedListType.cpp|35|error: expected '{' before 'exception'
UnsortedListType.cpp|35|error: 'exception' was not declared in this scope
UnsortedListType.cpp|35|error: expected ';' before ')' token
Everything I can find on this error says the problem is either an extra semicolon or a missing semicolon, either in the header or this file. I can't find an instance of either. And if I remove the try/catch block, it compiles fine.
Plus, if I catch an int, it compiles just fine:
template<class T>
bool UnsortedListType<T>::IsFull()
{
try { return false; }
catch(int exception) { return true; }
}
I can also catch(int) and it will compile just fine, but if I try to catch(std::bad_alloc) (i.e. with no "exception" variable name) it throws the same error listed above. Even if I try simply catch(std::exception) it fails to compile.
So now I'm stumped. I'm not an expert at C++ by any stretch, this is for a class, and I'm not sure how to get past this error.
Incidentally, here's the code from the non-generic version, which also compiles just fine, and is verbatim from the textbook I'm using (Dale, if anyone wonders):
bool UnsortedListType::IsFull() const
{
NodeType* location;
try
{
location = new NodeType;
delete location;
return false;
}
catch (std::bad_alloc exception)
{
return true;
}
}
I am using CodeBlocks 12.11 IDE on Windows 7 with the built-in GNU compiler.
Any help appreciated, and I'll be happy to post more code if requested, I just didn't want to fill the page up.
Many thanks in advance.
PS I should state, yes I am doing homework, but the homework doesn't call for me to make a template, I am choosing to go that route myself. Not sure if it has any relevance, but this is the first time I've used C++ templates, so just tossing that out there.
std::bad_alloc is defined in the header <new>, so you need to include that.
Also, it's better to catch exceptions by reference. Catching by value causes a copy, perhaps sliced, of the exception object to be made. Personally I make non-const reference a habit, allowing exception state to be added during handling, but most basic exception types are stateless so there's no practical difference between const & and non-const &.