[libc++] Is libc++ compatible with previous c++ language standard implementation

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

[libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
Hi, All.

Does anybody know that whether libc++ is compatible with previous c++ language standard implementation or not? For example, I know libc++ is now support c++11, I will show a example.

http://en.cppreference.com/w/cpp/container/vector/vector. In the reference, there are two different constructors for vector, 

explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator()); (until C++11) (1)
explicit vector( size_type count );(since C++11) (until C++14) (2)

If I use vector<T> a(1), which one will be chosen with different c++ std command option, such as -std=c++03, -std=c++11? Actually, I can not find the (1) version in libc++ source.

In my option, both two functions should be implemented and guarded by related language level macro, but I can not find in libc++ source. So libc++ is not compatible with previous c++ language standard implementation?

Thanks.

--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
I'm not sure about libc++'s support for pre-C++11, but I think it does support earlier standards. The constructor you're asking about isn't a great example to look at. The function signature (1) was split into two different functions in C++11 rather than using a defaulted argument. But the calling code shouldn't be able to tell the difference. It doesn't require any code changes on the user's part.

It also looks like even the defaulted argument for alloc is implemented in libc++ with different signatures which is different than what the spec says. But again user code can't tell.

~Craig

On Tue, Mar 6, 2018 at 10:38 PM, Zeson Wu via cfe-dev <[hidden email]> wrote:
Hi, All.

Does anybody know that whether libc++ is compatible with previous c++ language standard implementation or not? For example, I know libc++ is now support c++11, I will show a example.

http://en.cppreference.com/w/cpp/container/vector/vector. In the reference, there are two different constructors for vector, 

explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator()); (until C++11) (1)
explicit vector( size_type count );(since C++11) (until C++14) (2)

If I use vector<T> a(1), which one will be chosen with different c++ std command option, such as -std=c++03, -std=c++11? Actually, I can not find the (1) version in libc++ source.

In my option, both two functions should be implemented and guarded by related language level macro, but I can not find in libc++ source. So libc++ is not compatible with previous c++ language standard implementation?

Thanks.

--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
In reply to this post by Hans Wennborg via cfe-dev
As a template class, it is impossible to find the `std::vector` class in libc++. When writing a template class, all the code need during compile-time should be provided in the header file; and when compiling with a template class/function, the template parameter will be replaced with the concrete type/argument. As you can see, this is just a compile-time process rather than a link-time process, much less the libc++.

explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator()); (until C++11) (1)
explicit vector( size_type count );(since C++11) (until C++14) (2)

If I use vector<T> a(1), which one will be chosen with different c++ std command option, such as -std=c++03, -std=c++11? Actually, I can not find the (1) version in libc++ source.
Just as what I mentioned above, the answer is it depends. If you compile your code under standard C++11, (2) will be used; if you use previous standard, (1) will be used. (Also, it depends on the argument you provided, but the header file will deal with it.)
 
In my option, both two functions should be implemented and guarded by related language level macro, but I can not find in libc++ source. So libc++ is not compatible with previous c++ language standard implementation?
So, it is not weird to find nothing about that.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
Sorry to not reply to all. So FYI.
---------- Forwarded message ----------
From: Zeson Wu <[hidden email]>
Date: 2018-03-08 10:32 GMT+08:00
Subject: Re: [cfe-dev] [libc++] Is libc++ compatible with previous c++ language standard implementation
To: alan snape <[hidden email]>


What I mean above for libc++ is the source/header of libc++ library.

I can not find the prototype of (1). I just find

#if _LIBCPP_STD_VER > 11
explicit vector(size_type __n, const allocator_type& __a);
#endif
vector(size_type __n, const_reference __x);
vector(size_type __n, const_reference __x, const allocator_type& __a);

Is the implementation legal and to be suitable for all language level among 03, 11 and 14? But how to explain the case I showed before? The output of the case is different by gcc with option -std=c++11 and -std=c++03, but it's same by clang.

#include <iostream>
#include <vector>

struct T
{
   bool flag;
   T() : flag(false) {}
   T(const T&) : flag(true) {}
};


int main()
{
   std::vector<T> test(1);
   bool is_cpp11 = !test[0].flag;

   std::cout << is_cpp11 << std::endl ;
}
 



2018-03-08 10:09 GMT+08:00 alan snape <[hidden email]>:
As a template class, it is impossible to find the `std::vector` class in libc++. When writing a template class, all the code need during compile-time should be provided in the header file; and when compiling with a template class/function, the template parameter will be replaced with the concrete type/argument. As you can see, this is just a compile-time process rather than a link-time process, much less the libc++.

explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator()); (until C++11) (1)
explicit vector( size_type count );(since C++11) (until C++14) (2)

If I use vector<T> a(1), which one will be chosen with different c++ std command option, such as -std=c++03, -std=c++11? Actually, I can not find the (1) version in libc++ source.
Just as what I mentioned above, the answer is it depends. If you compile your code under standard C++11, (2) will be used; if you use previous standard, (1) will be used. (Also, it depends on the argument you provided, but the header file will deal with it.)
 
In my option, both two functions should be implemented and guarded by related language level macro, but I can not find in libc++ source. So libc++ is not compatible with previous c++ language standard implementation?
So, it is not weird to find nothing about that.



--
Zeson



--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
In reply to this post by Hans Wennborg via cfe-dev
Sorry to not reply to all. So FYI.

---------- Forwarded message ----------
From: Zeson Wu <[hidden email]>
Date: 2018-03-07 16:26 GMT+08:00
Subject: Re: [cfe-dev] [libc++] Is libc++ compatible with previous c++ language standard implementation
To: Craig Topper <[hidden email]>


although calling code shouldn't be able to tell the difference and it doesn't require any code changes on the user's part, I think the interface was changed and the semantic is also changed.
The following case will show different behavior. Or it's UB test point?

#include <iostream>
#include <vector>

struct T
{
   bool flag;
   T() : flag(false) {}
   T(const T&) : flag(true) {}
};


int main()
{
   std::vector<T> test(1);
   bool is_cpp11 = !test[0].flag;

   std::cout << is_cpp11 << std::endl ;
}
 
Anyway, I find gcc libstdc++ has a guard to implement different version as following? But llvm libc++ is not.

#if __cplusplus >= 201103L
/**
* @brief Creates a %vector with default constructed elements.
* @param __n The number of elements to initially create.
* @param __a An allocator.
*
* This constructor fills the %vector with @a __n default
* constructed elements.
*/
explicit
vector(size_type __n, const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_default_initialize(__n); }
/**
* @brief Creates a %vector with copies of an exemplar element.
* @param __n The number of elements to initially create.
* @param __value An element to copy.
* @param __a An allocator.
*
* This constructor fills the %vector with @a __n copies of @a __value.
*/
vector(size_type __n, const value_type& __value,
const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_fill_initialize(__n, __value); }
#else
/**
* @brief Creates a %vector with copies of an exemplar element.
* @param __n The number of elements to initially create.
* @param __value An element to copy.
* @param __a An allocator.
*
* This constructor fills the %vector with @a __n copies of @a __value.
*/
explicit
vector(size_type __n, const value_type& __value = value_type(),
const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_fill_initialize(__n, __value); }
#endif

 

2018-03-07 15:25 GMT+08:00 Craig Topper <[hidden email]>:
I'm not sure about libc++'s support for pre-C++11, but I think it does support earlier standards. The constructor you're asking about isn't a great example to look at. The function signature (1) was split into two different functions in C++11 rather than using a defaulted argument. But the calling code shouldn't be able to tell the difference. It doesn't require any code changes on the user's part.

It also looks like even the defaulted argument for alloc is implemented in libc++ with different signatures which is different than what the spec says. But again user code can't tell.

~Craig

On Tue, Mar 6, 2018 at 10:38 PM, Zeson Wu via cfe-dev <[hidden email]> wrote:
Hi, All.

Does anybody know that whether libc++ is compatible with previous c++ language standard implementation or not? For example, I know libc++ is now support c++11, I will show a example.

http://en.cppreference.com/w/cpp/container/vector/vector. In the reference, there are two different constructors for vector, 

explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator()); (until C++11) (1)
explicit vector( size_type count );(since C++11) (until C++14) (2)

If I use vector<T> a(1), which one will be chosen with different c++ std command option, such as -std=c++03, -std=c++11? Actually, I can not find the (1) version in libc++ source.

In my option, both two functions should be implemented and guarded by related language level macro, but I can not find in libc++ source. So libc++ is not compatible with previous c++ language standard implementation?

Thanks.

--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





--
Zeson



--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
OK, I got your meaning. Let's summarize the interfaces declared on http://en.cppreference.com/w/cpp/container/vector/vector and then go over the implementation of libc++ version.

On the site http://en.cppreference.com/w/cpp/container/vector/vector, the given interfaces are:
(2)
explicit vector( size_type count, 
                 const T& value = T(),
                 const Allocator& alloc = Allocator());
(until C++11)
         vector( size_type count, 
                 const T& value,
                 const Allocator& alloc = Allocator());
(since C++11)
(3)
explicit vector( size_type count );
(since C++11, until C++14)
explicit vector( size_type count, const Allocator& alloc = Allocator() );
(since C++14)
If you use `vector(1)`, format (2-1) will be used until c++11, format (3-1) will be used since c++11 until c++14 and format (3-2) will be used since c++14.
If you use `vector(1, T())`, format (2-1) will be used until c++11, format (2-2) will be used since c++11.
If you use `vector(1, T(), Allocator())`, format (2-1) will be used until c++11, format (2-2) will be used since c++11.
And you can use `vector(1, Allocator())` until c++14, where format (3-2) will be used.
And the above interfaces are right the same with the code provided by gcc (just as what you pasted in the previous mail).

Then, let's have a look at the libc++ version:
// libc++/include/vector:491~496: https://github.com/llvm-mirror/libcxx/blob/master/include/vector#L491
 
    explicit vector(size_type __n);  // (1)
#if _LIBCPP_STD_VER > 11
    explicit vector(size_type __n, const allocator_type& __a);  // (2)
#endif
    vector(size_type __n, const_reference __x);  // (3)
    vector(size_type __n, const_reference __x, const allocator_type& __a);  // (4)
If you use `vector(1)`, format (1) will be used.
If you use `vector(1, T())`, format (3) will be used.
If you use `vector(1, T(), Allocator())`, format (4) will be used.
And you can use `vector(1, Allocator())` until c++14, where format (2) will be used.
All the interfaces required are implemented, and clearer than the gcc version.

Did I managed to answer your question?

And go on with the test case you provided above, the differences between the two versions of header files make the different results. In gcc, format (2-1) will be used until c++11, which may contain value copy during construction, but the format (3-1) and format (3-2), which are used in c++11 and since c++14 respectively, do not have the value copy; while in clang, only format (1) will be used, and the behavior cannot be different.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
In clang, only format (1) will be used, so there is not copy construction in pre c++11, but there should be a copy construction as the reference declare "explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());".

2018-03-08 12:25 GMT+08:00 alan snape <[hidden email]>:
OK, I got your meaning. Let's summarize the interfaces declared on http://en.cppreference.com/w/cpp/container/vector/vector and then go over the implementation of libc++ version.

On the site http://en.cppreference.com/w/cpp/container/vector/vector, the given interfaces are:
(2)
explicit vector( size_type count, 
                 const T& value = T(),
                 const Allocator& alloc = Allocator());
(until C++11)
         vector( size_type count, 
                 const T& value,
                 const Allocator& alloc = Allocator());
(since C++11)
(3)
explicit vector( size_type count );
(since C++11, until C++14)
explicit vector( size_type count, const Allocator& alloc = Allocator() );
(since C++14)
If you use `vector(1)`, format (2-1) will be used until c++11, format (3-1) will be used since c++11 until c++14 and format (3-2) will be used since c++14.
If you use `vector(1, T())`, format (2-1) will be used until c++11, format (2-2) will be used since c++11.
If you use `vector(1, T(), Allocator())`, format (2-1) will be used until c++11, format (2-2) will be used since c++11.
And you can use `vector(1, Allocator())` until c++14, where format (3-2) will be used.
And the above interfaces are right the same with the code provided by gcc (just as what you pasted in the previous mail).

Then, let's have a look at the libc++ version:
// libc++/include/vector:491~496: https://github.com/llvm-mirror/libcxx/blob/master/include/vector#L491
 
    explicit vector(size_type __n);  // (1)
#if _LIBCPP_STD_VER > 11
    explicit vector(size_type __n, const allocator_type& __a);  // (2)
#endif
    vector(size_type __n, const_reference __x);  // (3)
    vector(size_type __n, const_reference __x, const allocator_type& __a);  // (4)
If you use `vector(1)`, format (1) will be used.
If you use `vector(1, T())`, format (3) will be used.
If you use `vector(1, T(), Allocator())`, format (4) will be used.
And you can use `vector(1, Allocator())` until c++14, where format (2) will be used.
All the interfaces required are implemented, and clearer than the gcc version.

Did I managed to answer your question?

And go on with the test case you provided above, the differences between the two versions of header files make the different results. In gcc, format (2-1) will be used until c++11, which may contain value copy during construction, but the format (3-1) and format (3-2), which are used in c++11 and since c++14 respectively, do not have the value copy; while in clang, only format (1) will be used, and the behavior cannot be different.



--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
In clang, only format (1) will be used, so there is not copy construction in pre c++11, but there should be a copy construction as the reference declare "explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());".
I don't know either why they did not... (Maybe this is the reason why this project was started. :-) )
The behavior is different, but the interfaces are compatible.
I suggest you to read the C++ standard, and maybe submit a patch to handle this issue. (If you would like to do that.)

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
I don't know whether it is a bug, or the execution of copy constructor does not matter.

In c++ standard, there are such rules:
  1. An implementation may declare additional non-virtual member function signatures within a class:

  • (2.1)  —  by adding arguments with default values to a member function signature;187 [ Note: An implementation may not add arguments with default values to virtual, global, or non-member functions. — end note ]

  • (2.2)  —  by replacing a member function signature with default values by two or more member function signa-tures with equivalent behavior; and 

           (2.3)  — by adding a member function signature for a member function name. 

So as the (2.2) said, for pre c++11, "explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());", could be replaced by such 3 functions ((1), (3), (4)) as libc++ did.

explicit vector(size_type __n);  // (1)
#if _LIBCPP_STD_VER > 11
    explicit vector(size_type __n, const allocator_type& __a);  // (2)
#endif
    vector(size_type __n, const_reference __x);  // (3)
    vector(size_type __n, const_reference __x, const allocator_type& __a);  // (4)

 So now I am wondering whether the execution of copy constructor is countered as equivalent behavior?

2018-03-08 14:40 GMT+08:00 alan snape <[hidden email]>:
In clang, only format (1) will be used, so there is not copy construction in pre c++11, but there should be a copy construction as the reference declare "explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());".
I don't know either why they did not... (Maybe this is the reason why this project was started. :-) )
The behavior is different, but the interfaces are compatible.
I suggest you to read the C++ standard, and maybe submit a patch to handle this issue. (If you would like to do that.)



--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev

On Thu, Mar 8, 2018 at 2:49 AM, Zeson Wu via cfe-dev <[hidden email]> wrote:
I don't know whether it is a bug, or the execution of copy constructor does not matter.

In c++ standard, there are such rules:
  1. An implementation may declare additional non-virtual member function signatures within a class:

  • (2.1)  —  by adding arguments with default values to a member function signature;187 [ Note: An implementation may not add arguments with default values to virtual, global, or non-member functions. — end note ]

  • (2.2)  —  by replacing a member function signature with default values by two or more member function signa-tures with equivalent behavior; and 

           (2.3)  — by adding a member function signature for a member function name. 

So as the (2.2) said, for pre c++11, "explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());", could be replaced by such 3 functions ((1), (3), (4)) as libc++ did.

explicit vector(size_type __n);  // (1)
#if _LIBCPP_STD_VER > 11
    explicit vector(size_type __n, const allocator_type& __a);  // (2)
#endif
    vector(size_type __n, const_reference __x);  // (3)
    vector(size_type __n, const_reference __x, const allocator_type& __a);  // (4)

 So now I am wondering whether the execution of copy constructor is countered as equivalent behavior?

2018-03-08 14:40 GMT+08:00 alan snape <[hidden email]>:
In clang, only format (1) will be used, so there is not copy construction in pre c++11, but there should be a copy construction as the reference declare "explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());".
I don't know either why they did not... (Maybe this is the reason why this project was started. :-) )
The behavior is different, but the interfaces are compatible.
I suggest you to read the C++ standard, and maybe submit a patch to handle this issue. (If you would like to do that.)



--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
Yes, how about the result? So I do not know the way libc++ source do that losing semantic of copy construction is legal or not.

BTW, hmmmm, interesting email address name. 😀😂

2018-03-08 23:01 GMT+08:00 Hubert Tong <[hidden email]>:

On Thu, Mar 8, 2018 at 2:49 AM, Zeson Wu via cfe-dev <[hidden email]> wrote:
I don't know whether it is a bug, or the execution of copy constructor does not matter.

In c++ standard, there are such rules:
  1. An implementation may declare additional non-virtual member function signatures within a class:

  • (2.1)  —  by adding arguments with default values to a member function signature;187 [ Note: An implementation may not add arguments with default values to virtual, global, or non-member functions. — end note ]

  • (2.2)  —  by replacing a member function signature with default values by two or more member function signa-tures with equivalent behavior; and 

           (2.3)  — by adding a member function signature for a member function name. 

So as the (2.2) said, for pre c++11, "explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());", could be replaced by such 3 functions ((1), (3), (4)) as libc++ did.

explicit vector(size_type __n);  // (1)
#if _LIBCPP_STD_VER > 11
    explicit vector(size_type __n, const allocator_type& __a);  // (2)
#endif
    vector(size_type __n, const_reference __x);  // (3)
    vector(size_type __n, const_reference __x, const allocator_type& __a);  // (4)

 So now I am wondering whether the execution of copy constructor is countered as equivalent behavior?

2018-03-08 14:40 GMT+08:00 alan snape <[hidden email]>:
In clang, only format (1) will be used, so there is not copy construction in pre c++11, but there should be a copy construction as the reference declare "explicit vector( size_type count, const T& value = T(), const Allocator& alloc = Allocator());".
I don't know either why they did not... (Maybe this is the reason why this project was started. :-) )
The behavior is different, but the interfaces are compatible.
I suggest you to read the C++ standard, and maybe submit a patch to handle this issue. (If you would like to do that.)



--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





--
Zeson

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [libc++] Is libc++ compatible with previous c++ language standard implementation

Hans Wennborg via cfe-dev
On Thu, Mar 8, 2018 at 10:31 AM, Zeson Wu <[hidden email]> wrote:
Yes, how about the result? So I do not know the way libc++ source do that losing semantic of copy construction is legal or not.
I am not aware of there being direction from the committee to make it legal; however, that possibility has not been rejected either.
 

BTW, hmmmm, interesting email address name. 😀😂

2018-03-08 23:01 GMT+08:00 Hubert Tong <[hidden email]>:



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev