[LLVMdev] patch for portability

Howard Hinnant hhinnant at apple.com
Thu Dec 3 06:29:18 PST 2009


On Dec 3, 2009, at 5:24 AM, Ahmed Charles wrote:

> Sorry, always end up not replying to the list:
> 
> The main issue with dealing with next this way is that people adding new uses of next will probably not be using c++0x and therefore won't know it's ambiguous and that it needs to be qualified.

True.  But when this code is compiled under C++0X you get an easy to diagnose, easy to fix, compile-time diagnostic (as opposed to a hard-to-find run time error).

On Dec 3, 2009, at 5:32 AM, OvermindDL1 wrote:

> What does llvm::next do that std::next (or boost::next) do not do?  If
> they do the same thing, why not just conditional create llvm::next, if
> std::next is available then just include it into the llvm namespace so
> it can be used as they currently are.  If they are not compatible, why
> not fix the iterators to follow the std standards?

They all look identical to me.  The conditional creation of llvm::next is a viable, yet more complicated solution.

Note that this is a larger issue than just next().  The C++0X standard is introducing several new generic free functions in several existing headers:

<iterator>
   next
   prev
   begin
   end

<utility>
   move
   forward

<memory>
   addressof
   undeclare_reachable

<functional>
   ref
   cref
   bind

<algorithm>
   all_of
   any_of
   none_of
   move
   copy_if

<numeric>
   iota

(this is not a complete list).  Additionally when /any/ two libraries are mixed (e.g. llvm and boost), there is a large potential for name clashes even when namespaces are judiciously used.  The carefully crafted C++ library should be aware of ADL issues.  It should know when ADL is being used, and when it isn't, and use ADL purposefully, not accidentally.

> There are also two issues with rvalue references and the STL:
> 
> 1. EquivalenceClasses, in the insert and findLeader functions, it uses map functions which have versions taking rvalue references. This results in a compiler error because the private constructor of ECValue is inaccessible. The easiest fix is to explicitly call the constructor of ECValue before the insert/find calls.

If I'm understanding the concern, this looks easy to fix to me by simply making the private construction explicit within the scope of the code which has access to this constructor:

  iterator insert(const ElemTy &Data) {
    return TheMapping.insert(ECValue(Data)).first;
  }

You can make this change today, and it will work with your C++03 compiler with no loss of efficiency, and arguably improved clarity.

> 2. There are numerous places where there is a std::pair of pointer types and passing 0 results in the rvalue reference constructor being called. The type of 0 is deduced to be an int and an int isn't convertable to a pointer, so it fails to compile. The fix is to use nullpte (GCC doesn't seem to have this yet) or to static_cast<T*>(0) where T is the appropriate type.

I anticipate a standards fix for this one.  The pair<T1, T2>::pair<U, V>(U&&, V&&) constructor should not participate in overload resolution unless U is implicitly convertible to T1 and V is implicitly convertible to T2 (easily implemented with enable_if and is_convertible).  pair is still a hotbed of controversy on the committee, but I expect it to be greatly simplified over its current form prior to ratification.

-Howard





More information about the llvm-dev mailing list