By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,952 Members | 1,384 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,952 IT Pros & Developers. It's quick & easy.

Why a vector<long long> can't be assigned a vector<int64_t> on a Linux 64bits compile

P: 2
Here is a small C++ puzzling problem which blocks me in my current developments and I will appreciate any idea or explanation.

Consider the following C++ program :

Expand|Select|Wrap|Line Numbers
  1. #include <stdint.h>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. int main(int argC, char* argV[]) {
  6. vector<int64_t> v64;
  7. vector<long long> vll;
  8.  
  9. vll = v64;
  10. }
  11.  
On my Mac with gnu c++ (i686-apple-darwin10-g++-4.2.1) it compiles perfectly. On my SL 5.3 32 bits it compiles as well. *But* on a Centos 5.5 64bits with gnu c++ configured as follows :

Expand|Select|Wrap|Line Numbers
  1. aramis2 caillat:/tmp 510 > g++ -v
  2. Utilisation des specs internes.
  3. Target: x86_64-redhat-linux
  4. Configuré avec: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
  5. Modèle de thread: posix
  6. version gcc 4.1.2 20080704 (Red Hat 4.1.2-48)
  7.  
it fails to compile and gives the following error message :

Expand|Select|Wrap|Line Numbers
  1. aramis2 caillat:/tmp 511 > g++ t64.cpp 
  2. t64.cpp: In function ‘int main(int, char**)’:
  3. t64.cpp:12: erreur: no match for ‘operator=’ in ‘vll = v64’
  4. /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/vector.tcc:133: note: candidats sont: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = long long int, _Alloc = std::allocator<long long int>]
  5. aramis2 caillat:/tmp 512 > 
  6.  
i.e. the 'long long' are not considered as equiv to 'int64_t' when they are the base type of a vector... Do you have an idea about the reason of this behaviour (shame on me if it's obvious) ?

What's even more surprising is that the compiler does not complain in front of a assignment statement where lhs is long long and rhs is int64_t but operands are scalar.
Nov 4 '10 #1
Share this Question
Share on Google+
3 Replies


Banfa
Expert Mod 5K+
P: 8,916
Interesting, the problem is at the class level, that is as far as the compiler is concerned vector<int64_t> and vector<long long> are not the same type so you can't pass vector<int64_t> to a function which effectively has the prototype vector<long long>::operator=(const vector<long long>&); because they are not the same class type.

This is how templates are meant to work, instantiations with different types are not the same class.

I also not that int64_t is not current a C++ standard type but rather a C90 type. You may want to check how they are defined on both systems.

And of course since the compilers are different versions 4.2.1 and 4.1.2 they may have different behaviour and you would expect 4.2.1 to have better behaviour.

Finally being able to assign the pod types int64_t and long long to each other has no bearing on the problem because the compiler has many ways to promote and convert between pod types but the issue at point is class assignment and the compiler can only do that with the supplied assignment operators.


And even more finally I assume you are aware you can easily work round this issue in several ways, e.g. use std::copy?
Nov 4 '10 #2

P: 2
Hi Banfa,

Thank you very much for your commented answer to my question. Yes the std::copy algorithm would be an elegant workaround, but unfortunately the problem I have to solve is due to a code which is generated (by SWIG not to name it :-)) not a code which is handwritten.
Nov 4 '10 #3

Banfa
Expert Mod 5K+
P: 8,916
A-ha, well then in that case manually code a non member copy operator vector<long long>& operator=(vector<long long>&, const vector<long long>&);.

You would have to get its prototype into a header that is seen by the generated code.
Nov 4 '10 #4

Post your reply

Sign in to post your reply or Sign up for a free account.