(Still) be explicit to avoid those array/pointer decay ambiguities
I'm multitasking between three clients at the moment, two of whose projects are based primarily around C++. It's interesting seeing the differences between all the languages, programming styles, and tools, involved. For a consultant - horrid word - it's a refreshing and enlightening experience.
Although there is a C standard and a C++ standard, there are also different degrees of support for the standards by different compilers, not to mention some subtle (and some not-so-subtle) extensions and non-standard features. Consequently, there are myriad ways in which competent programmers can find themselves mired in incompatibilities. And that can even happen when they're adhering to the standard(s)!
Back in 2004, in my book Imperfect C++, I discussed the problems that arise from C/C++'s array-pointer duality (recently raised again by Walter Bright in this arena), and offered advice on techniques for preventing or avoiding it. For example, if you want to write (generic) code that works with a pointer as well as it does with an instance of std::vector (or any other type providing contiguous storage and a subscript operator), you should not rely on the decay of the array into a pointer:
int ar; <br /> std::vector<int> v; <br /> int* p; <br /> <br /> p = ar; // 1. ok <br /> p = v; // 2. compile error
but rather take a pointer explicitly via the address-of and subscript operators:
p = &ar; // 3. ok <br /> p = &v; // 4. ok (as long as !v.empty())
Hard as it is for me to imagine or accept, it seems that not everyone's read it yet, and some of the advice therein has failed to percolate as far as (I think) it should have.
We're running into such an issue in one of the commercial projects I'm currently involved with. The extant code, written for/with GCC, makes use of C99's (standard) Variable Length Arrays. Unfortunately, these are not wholly supported by all the compilers to which we're porting the codebase. This (and a bunch of other good reasons why VLA's are not suitable for use in C++) require that we substitute a more portable alternative: I advised STLSoft's auto_buffer class template, which represents a better choice for VLAs for C++.
Had the code been written with the explicit subscript/address-of operators, the change would have involved only a single line. However, the code relies on VLAs' implicit decay-to-pointer, and pointers to the array are achieved by the implicit syntax (1). So, in order to provide a clear path in the source code management's history, we're taking two passes at the code: the first pass to change implicit syntax to explicit, the second (and now simple) pass to change the array types.
Interesting, the syntax for real arrays has another valid form (the reasons for which are discussed in Peter van der Linden's excellent Deep C Secrets):
p = &0[ar]; // 3. ok <br /> p = &0[v]; // 4. compile error
This can be put to good use in applying constraints to, and discriminating between, arrays and (instances of) user-defined types, but the explanations are too lengthy for this forum; feel free to get the book and see for yourself.