Thread Warning Help :(

This is a discussion on Thread Warning Help :( within the C++ Programming forums, part of the General Programming Boards category; Hey, so I'm doing a project for one of my classes that requires part of it to be multi-threaded. Unfortunately, ...

  1. #1
    Registered User
    Join Date
    Aug 2010
    Location
    Rochester, NY
    Posts
    196

    Thread Warning Help :(

    Hey, so I'm doing a project for one of my classes that requires part of it to be multi-threaded.

    Unfortunately, I am working on a Solaris box (as that's what it will be tested on) with a SPARC based processor. Also, unfortunately, I am using "CC" (I believe version 5.9) - not "g++" or anything.

    Anywho, I'm trying to spawn a new thread using thr_create() - and I keep getting this warning - and I can't make it go away!!

    I'm calling it like this:
    Code:
    thr_create(NULL, 0, ThreadTaskLoop, NULL, THR_DETACHED, NULL);
    I'm getting this warning message:
    Code:
    "tcp-project2.C", line 146: Warning (Anachronism): Formal argument 3 of type extern "C" void*(*)(void*) in
    call to thr_create(void*, unsigned, extern "C" void*(*)(void*), void*, long, unsigned*) is being passed void*(*)(void*).
    1 Warning(s) detected.
    I CAN'T MAKE IT GO AWAY!!! - I've been at it for like an hour...

    Initially I wanted to pass it a pointer to a struct, but I gave up on that (asking way too much of CC, apparently) - I just want it to stop warning.

    Initially I had:
    Code:
    thr_create(NULL, 0, ThreadTaskLoop, (void*)&args, THR_DETACHED, NULL);
    Where "args" is a struct.

    The prototype for the function, even though I only want to pass it a struct pointer, and have no return, is this:
    Code:
    void* ThreadTaskLoop(void*);
    I realize that since the thr_create prototype expects a function pointer with a void* parameter and void* return I can't do anything about that, but OMG, I just want the stupid thing to compile without this warning.

    I am completely OK not passing it jack ........ at the moment.

    I also tried doing this:
    Code:
    thr_create(NULL, 0, ThreadTaskLoop, (void*)0, THR_DETACHED, NULL);
    Understanding the possibility that the NULL macro may not be defined as:
    Code:
    #define NULL (void*)0
    Same thing.

    Pleeeeeease make it go away!!!

    TIA

    EDIT:
    I tried like 100 other things, too, just listed the things I expected to work here. Please don't tell me to search - I've searched, and searched, and searched, and searched.

    I do see a lot of people (ie. Oracle official documentation) passing it an integer cast to a void*. Unfortunately I don't need to give my function an integer, and even if I did - I tried - I get the same warning message upon compilation.
    Last edited by Syndacate; 10-21-2010 at 04:59 AM. Reason: Clarifying how much of a pain in my ass this issue is..

  2. #2
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,587
    The warning is about parameter 3, the address to a function. Apparently your type is extern "C", which the compiler doesn't like for some reason. Also, your function is not returning nothing, it's returning void*.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,284
    Declare ThreadTaskLoop() to be an extern "C" function.
    Code:
    extern "C" void* ThreadTaskLoop(void*);
    The reason is that, in C++, linkage (such as extern "C") is part of the type specification for a function. The reason is that function linkage can affect the mechanism the compiler uses to pass arguments.

    You'll also need to adorn the definition (i.e. implementation) of the function as extern "C".
    Right 98% of the time, and don't care about the other 3%.

  4. #4
    Registered User
    Join Date
    Aug 2010
    Location
    Rochester, NY
    Posts
    196
    Quote Originally Posted by Elysia View Post
    The warning is about parameter 3, the address to a function. Apparently your type is extern "C", which the compiler doesn't like for some reason. Also, your function is not returning nothing, it's returning void*.
    A) Yeah, I understand where the error message is happening
    B) My type isn't extern "C" - that's what the prototype expects.
    C) I don't *want* to return anything, but the function prototype for the function pointer specifies that I return a void*, not void.

    Quote Originally Posted by grumpy View Post
    Declare ThreadTaskLoop() to be an extern "C" function.
    Code:
    extern "C" void* ThreadTaskLoop(void*);
    The reason is that, in C++, linkage (such as extern "C") is part of the type specification for a function. The reason is that function linkage can affect the mechanism the compiler uses to pass arguments.

    You'll also need to adorn the definition (i.e. implementation) of the function as extern "C".
    I just externed the declaration and it worked like a charm - you rock. I did *not* need to extern the definition.

    I see, but it's expecting a void*, so shouldn't it just resolve the function pointer with a void* type as the parameter and be on its merry way? It shouldn't care what I decide to stuff in that pointer, no?

    I had no idea this would make the slightest bit of difference. If the parameter was declared as extern in the function prototype, it should have waited until linking to resolve the addr....which it would have had at link time, ie. no problem. I can see WHY somebody would extern it - as in it was being called from another object mod or something, but I don't see why the heck my function has to be externed as well. Should be defined/declared wherever it is, and its addr should be taken at link time, when the called function's extern'ed parameter is resolved, no?

    Thanks soooooooooooooooooooo much, that was so much time that I just spent getting more and more ........ed off. That really shouldn't have mattered IMO

  5. #5
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,587
    I have to say, that is the worst error message I have seen to date.
    It isn't clear what it's expecting and what type you pass.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,668
    >> that is the worst error message I have seen to date
    I don't think it's that bad:
    Formal argument 3 of type
    extern "C" void*(*)(void*)
    ... is being passed
    void*(*)(void*).
    Looking at the expected type and given type - first thing I see is that the stuff in red is missing....

    >> it should have waited until linking to resolve the addr....
    Don't confuse "external linkage" with "language linkage" - which can affect things like name-mangling and calling-conventions - things the compiler/linker may need to know.

    'extern "C"' provides external linkage as well - even though that's not what fixed the warning.

    >> I am using "CC" (I believe version 5.9) - not "g++" or anything.
    Sun/Oracle CC supports Posix threads as well (which probably just calls thr_create et al. under-the-hood). Using Posix threads you could at least play with your code at home on your Linux box - or even Windows with Pthreads-w32.

    gg

  7. #7
    Registered User
    Join Date
    Aug 2010
    Location
    Rochester, NY
    Posts
    196
    Quote Originally Posted by Elysia View Post
    I have to say, that is the worst error message I have seen to date.
    It isn't clear what it's expecting and what type you pass.
    It seemed to me like it just expected a function pointer with a void* param and a void* return. I don't know why the extern made a difference. Regardless, what really killed me about that error message was the type (Anachronism) - say what? I agree, though, which is why I said at the beginning I was using CC - the error messages it generates are a lot more painful to read, IMO, than that of g++. I pretty much only use g++.

    Quote Originally Posted by Codeplug View Post
    >> that is the worst error message I have seen to date
    I don't think it's that bad:
    Looking at the expected type and given type - first thing I see is that the stuff in red is missing....
    Yeah, but it's like a const in the prototype declaration, but you pass it a non-const value - sometimes it just "shouldn't" matter if it's there, y'know? The parameter is its declaration, its re-declaration was simply externed, I still don't see why it was even an error.

    Quote Originally Posted by Codeplug View Post
    >> it should have waited until linking to resolve the addr....
    Don't confuse "external linkage" with "language linkage" - which can affect things like name-mangling and calling-conventions - things the compiler/linker may need to know.

    'extern "C"' provides external linkage as well - even though that's not what fixed the warning.
    By language linkage, do you mean like, binding variables to memory locs and the like?

    Quote Originally Posted by Codeplug View Post
    >> I am using "CC" (I believe version 5.9) - not "g++" or anything.
    Sun/Oracle CC supports Posix threads as well (which probably just calls thr_create et al. under-the-hood). Using Posix threads you could at least play with your code at home on your Linux box - or even Windows with Pthreads-w32.

    gg
    Yeah, I seriously considered using pthreads, but since Solaris doesn't appear to be 100% POSIX compliant, I opted against it. The documentation from Oracle specifically illustrates (in a code example) using a POSIX implementation vs using their implementation.

    I was working remotely, so I was still working "from home" - if I was making this app for myself (eg. a non-school project) it would [try to] comply to POSIX standards and use pthreads.

    EDIT:

    Also, as for this:
    Code:
    Formal argument 3 of type
    extern "C" void*(*)(void*)
    ... is being passed
    void*(*)(void*).
    It made it sound like the parameter (arg 4) being passed to the function pointer (arg 3) in the thr_create() function was a function ptr with a void* return and a void* param. It was almost like it was telling me I passed the function pointer a function pointer. Semantically, that appears to be what it's saying. That threw me, too.
    Last edited by Syndacate; 10-21-2010 at 10:58 AM.

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,668
    >> Yeah, but it's like a const ...
    Not really. Language linkage is part of the function type. So with and without 'extern "C"', you have two different types. Those [function pointer] types can then be cv-qualified as needed. So const or not, the type is wrong.

    >> By language linkage, do you mean ...
    What it really means [under the hood] is implementation defined. In practice, it can affect implementation details like calling convention and name-mangling.

    thr_create() is part of a C library, compiled by a C compiler. So the function pointer it's given needs to be C-compatible - not have any C++ things about it that would cause the already-C-compiled code to barf when calling the given function.

    http://docs.sun.com/source/819-3689/...ml#pgfId-18041

    >> but since Solaris doesn't appear to be 100% POSIX compliant
    Well, for the pthreads portion of Posix, you should have enough compliance for your purposes (even in pthreads-w32 most likely).

    If you believe wikipedia....
    http://en.wikipedia.org/wiki/POSIX#F...OSIX-compliant

    gg

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Quote Originally Posted by Syndacate View Post
    It seemed to me like it just expected a function pointer with a void* param and a void* return. I don't know why the extern made a difference.
    It's a difference in how C and C++ function names are encoded in object files. Read the examples here : Mixed-Language Programming and External Linkage. Did you

    Regardless, what really killed me about that error message was the type (Anachronism) - say what?
    I usually take this to mean something like : this code is broken but you got lucky and it still did what you intended even though its wrong. Now we're being more strict because the standard requires it. In other words, it was working before but shouldn't have and now it's likely to break at any time. We're being nice by at least warning you it's going to explode.

    And if that's really the worst error you've ever seen from a C++ compiler, you're obviously not using the STL.
    Code:
    stl.c: In function 'int main()':
    stl.c:10: error: no matching function for call to 'std::vector<int, std::allocator<int> >::insert(int)'
    c:\mingw-tdm-440\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/vector.tcc:106: note: candidates are: __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp
    , _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp,_Alloc>::insert(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Al
    loc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = int, _Alloc = std::allocator<int>]
    c:\mingw-tdm-440\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/stl_vector.h:850: note:                 void std::vector<_Tp, _Alloc>::insert(__gnu_cxx::__normal
    _iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, size_t, const _Tp&) [with _Tp = int, _Alloc = std::alloc
    ator<int>]
    Last edited by KCfromNC; 10-21-2010 at 04:05 PM.

  10. #10
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,587
    Oh, believe me, dealing heavily with templates, such errors are standard meal for me.
    But at least the error message is clear and it is usually easy to find what info you need. And that g++ output is a mess. Visual C++'s error messages are much more descriptive.

    I've even managed to crash the compiler on more than a few occasions.

    The error message made it rather difficult to know what the type which was passed was and the type the function accepted was.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. crashing program, help
    By xniinja in forum Windows Programming
    Replies: 1
    Last Post: 07-07-2010, 03:57 PM
  2. warning: excess elements in array initializer
    By redruby147 in forum C Programming
    Replies: 6
    Last Post: 09-30-2009, 06:08 AM
  3. GradeInfo
    By kirksson in forum C Programming
    Replies: 23
    Last Post: 07-16-2008, 03:27 PM
  4. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  5. DLL compiling question
    By Noose in forum Windows Programming
    Replies: 2
    Last Post: 12-16-2004, 06:16 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21