Find the answer to your Linux question:
Results 1 to 7 of 7
Hello All I have a compilation error in a very large program. We have managed to isolate the problem with the following test problem: Code: #include <vector> #include <iostream> using ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jul 2009
    Posts
    4

    Cannot convert int (aka NULL) to std::vector<double*>::value_type


    Hello All

    I have a compilation error in a very large program. We have managed to isolate the problem with the following test problem:

    Code:
    #include <vector>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        double* myPointer=NULL;         // no error on this line
        vector<double*> myVect(1,NULL); // error on this line
        return 0;
    }
    Compiling this spits out the error:

    Cannot convert 'int' to 'std::vector<double*>::value_type {aka double*}'

    When I compile this on GNU gcc compiler version 4.5.1 I do not get this error. When I compile it on GNU gcc compiler version 4.7.1 I get the error.

    Since the first reference to NULL works then we can conclude that NULL is defined and it can be used to initialize pointers. However when NULL is passed as an initialization to a std::vector container it is no longer type compatible.

    First Question: Is this a bug in the 4.7.1 compiler or did the compiler change to conform to some standard that does not allow vector's to initialized to NULL.

    I know there is an easy fix. However I have a large amount of code that has 8000+ instances of the work 'NULL'. I do not want to change all those instances to something like '(type*)0' just to find out later that this is a compiler error.

    Second Question: Is there a simple work around so I do not have to change all those instances of NULL?

    I know that I can stick with the 4.5.1 version of gcc. However if this is a permanent change in the compiler then I want to make the code work in future versions of g++.

    Thanks
    Mike

  2. #2
    Linux Enthusiast
    Join Date
    Jan 2005
    Location
    Saint Paul, MN
    Posts
    649
    In C++, NULL is not typed and must be cast to the proper type.

    For example if the argument is of type
    Code:
    std::vector<double*>
    then to pass NULL as the argument, you would need to use
    Code:
     (std::vector<double*>)NULL

  3. #3
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,596
    NULL is defined in the C header stddef.h and is usually defined as
    Code:
    ((void*)0)
    This means that you cannot use it in a C++ structure such as your vector<double*>. However, with C++ you can simply use 0 and it will be cast appropriately, so either do this
    Code:
    vector<double*> myVect(1, 0);
    or better still, this
    Code:
    vector<double*> myVect(1, (double*)0);
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  4. #4
    Just Joined!
    Join Date
    Jul 2009
    Posts
    4
    Hi there

    Thanks a lot for the help. So this:

    vector<double*> myVect(1, 0);

    Does not work. The compiler defaults an integer token as a type 'int' and fails to convert it to 'std::vector<double*>::array_type. I want to know whether this is a compiler bug or whether the latest version of gcc conforms to a standard that does not allow std::vector<double*> to be initialized by '0'

    That code worked on an old gcc version. The same error is all over in a very large body of code. I want to know if this is a bug or conformance. Ie do I fix my code because it is not conforming or do I get the bug fixed in gcc. Both jobs are a lot of work.

    Thanks
    Mike

  5. #5
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,596
    It may be that you cannot insert a null value in the vector. My guess is conformance is the issue. Also, I think that 4.7.x is a C++11 compiler, and a lot of changes have occurred that may cause this, including introduced bugs. Is there any specific reason why you cannot use 4.5 instead? That was wet paint as recently as last year. I had to build it from source on my Scientific Linux (RHEL) 6.3 system this past year in fact.

    Back to code. Your usage is what is called the "fill" constructor. The vector is constructed with the specified number of elements and then filled with copies of the element passed. Here is the actual signature:
    Code:
    explicit vector (size_type n, const value_type& val = value_type(),
                     const allocator_type& alloc = allocator_type());
    So, since this is a reference to the type (a double* in your case), it has to construct a temporary object to pass. So, perhaps you can do this (I'm just swagging it now since I don't have a 4.7 compiler handy!):
    Code:
    #include <vector>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        double* myPointer=0;
        vector<double*> myVect(1,myPointer); // use explicit object/pointer to construct vector.
        return 0;
    }
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  6. #6
    Just Joined!
    Join Date
    Jul 2009
    Posts
    4
    Thanks for the feedback. It seems that GCC 4.7 support for C++ 11 standard is still in development and is only active with the compiler flag. I am leaning towards fixing my code. it bugs me because vector should be able to accept null... Oh well.

  7. #7
    Just Joined!
    Join Date
    Jul 2009
    Posts
    4
    Hello All

    I looked into this through a couple forums and have come up with many resolutions and explanations. For the benefit of everyone else I am posting the results here. So yes this was an error in the standard:

    open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#438
    open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#1234

    This was addressed in the C++11 standard and then reported as a bug for GCC and fixed in the 4.8.0 version:

    gcc.gnu.org/bugzilla/show_bug.cgi?id=43813

    Some details on the bug is that it resolves to the following constructor: vector(iterator,iterator) as appose to vector(size_t,value_t). This error has been a problem since versions earlier than 4.5.1. It only happens on 32 bit versions of gcc.

    Some valid one line work-a-arounds:

    1) redefine NULL as 'null_ptr'
    2) redefine NULL as '0L' as it is in the 64bit version

    Alternate fixes for each instance of vector<T*> myVect(size,NULL):

    1) vector<T*> myVect(size,0L)
    2) vector<T*> myVect(size,null_ptr)
    3) vector<T*> myVect(size,(T*)NULL)
    4) vector<T*> myVect(size,static_cast<T*>(NULL))

    I need to check to see if this works on my colleagues computer. My version of GCC works.

    Take Care
    Mike

    Note that this forum is not allowing me to post url's it is annoying.... I know I know... spammers.... so yeah just prepend that http : // stuff to the links I posted...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •