[C++] Embarcadero C++ Builder is a joke

Last week I discovered that Embarcadero offers a free version of C++ Builder Starter, apparently for a limited period. So I took this opportunity to install the IDE and try to compile ArduinoJson.

It turned out to be a very disappointing (nearly infuriating) experience.

BTW, if you try to get a license don't be fooled by the first step that just requires an email address. To install the IDE, you'll have to create an account on EDN and provided your name, address and phone number.

Context

As a reminder, ArduinoJson is a JSON library that I wrote, and it contains a test suite using the Google Test framework.

I do the continuous integration with the following compiler:

  • Visual Studio 2010, 2012, 2013 and 2015
  • GCC 4.4.7, 4.5.3, 4.6.4, 4.7.3, 4.8.1, 4.9.2 and 5.4.0
  • Clang 3.4.0, 3.5.0, 3.6.2, 3.7.1 and 3.8.1

This is by many standards considered as "portable code," so porting it to another C++ compiler should be a piece of cake.

"Create project" doesn't work

I wasn't able to create a project, see the GIF below.

Can't create a C++ console app

I decided to go on with the command line, leveraging the "Borland Makefiles" generator of CMake.

std::vector constructor is broken

You cannot construct a std::vector<std::string> from an array of const char*

gtest-1.7.0\src\gtest-all.cc:  
Error E2285 gtest-1.7.0\src/gtest.cc 1786: Could not find a match for 'internal::Strings::vector(const char * const *,const char * const *)' in function testing::internal::Strings ArrayAsVector<8>(const char * ( &) const[8])  

The following code:

template <int kSize>  
 std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
 return std::vector<std::string>(array, array + kSize);
}

has to be changed to:

template <int kSize>  
std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {  
  std::vector<std::string> result;
  for (int i=0; i<kSize; ++i) {
    result.push_back(array[i]);
  }
  return result;
}

Conditional operator is broken

The conditional operator is not able to call an implicit conversion constructor:

Error E2354 gtest-1.7.0\src/gtest-test-part.cc 53: Two operands must evaluate to the same type in function TestPartResult::ExtractSummary(const char *)  

The following code:

return stack_trace == NULL ? message : std::string(message, stack_trace);  

has to be changed to:

return stack_trace == NULL ? std::string(message) : std::string(message, stack_trace);  

Name resolution is broken

Sometimes, the compiler is not able to find a function even if it has been properly defined earlier:

gtest-1.7.0\src/gtest.cc 3276: Call to undefined function 'GetReservedAttributesForElement' in function XmlUnitTestResultPrinter::OutputXmlAttribute(ostream *,const std::string &,const std::string &,const std::string &)  

(for the record, that function is defined at line 1794 of that file)

So the following code:

const std::vector<std::string>& allowed_names = GetReservedAttributesForElement(element_name);  

has to be changed to:

std::vector<std::string> GetReservedAttributesForElement(const std::string&);

const std::vector<std::string>& allowed_names = GetReservedAttributesForElement(element_name);  

#pragma once is broken

#pragma once doesn't work. At first, I believed that this was due to the .. in the path, but I now think it's not implemented at all.

Error E2238 ArduinoJson/test/../include\ArduinoJson/Internals/../Print.hpp 17: Multiple declaration for 'Print'  
Error E2344 ArduinoJson/test/../include\ArduinoJson/Internals/../Internals/../Print.hpp 17: Earlier declaration of 'Print'  

Solution: replace all #pragma once by #ifndef / #define / #endif include guard, just like it 1990 again!
I thought it was the end, so I did!!!!

Reference initialization is broken

Reference initialization is not able to trigger implicit conversion:

Error E2357 Reference initialized with 'JsonVariant', needs lvalue of type 'JsonArray'  

The following code:

JsonVariant variant;  
JsonArray& array = variant;  

has to be changed to:

JsonVariant variant;  
JsonArray& array = variant.as<JsonArray>();  

I had to stop my investigation here because ArduinoJson heavily relies on this. Hopefully the version 6 will solve that but for now, I have to surrender.

Conclusion

This compiler is a piece of crap and even if it's free, I don't see any valid reason to use it.
It's stuck in the 90's and even at that time, I would have considered as a piece of crap.
I'm really questioning the way they test their compiler because Google Test is quite common and has been for years.

Don't loose your time like me, go and download GCC, Clang or Visual Studio; there are free too, but they can actually compile C++.