PDA

View Full Version : Can you compile this in XCode? (const class initialization)


ksz
Nov 3, 2003, 02:52 PM
To familiarize myself with the C++ compiler in XCode, I've been running through a number of code examples from Scott Meyer's "Effective C++". However, the following code snippet based on Item 25 gives me a 'const class initialization' error or something to this effect. I don't have access to XCode at the moment, but the same snippet on Microsoft Visual C++ .NET compiles and runs with no warnings and, of course, no errors.

Try this:

#include <iostream>

using namespace std;

// Declare an anonymous const class with template
// type-conversion functions. The first one converts
// NULLPTR to any type of null non-member pointer.
// The second achieves the same result for any type
// of null *class member* pointer.
const class
{
public:
template<class T>
operator T*() const { return 0; }

template<typename C, typename T>
operator T C::*() const { return 0; }

private:
// suppress address-of operator because it
// is meaningless to take the address of this
// null pointer
void operator&() const;

} NULLPTR;

// Create a set of overloaded functions to try this out.
// First takes an int, second takes a char*.

void f(int x)
{
cout << "f(int x) has been called\n";
return;
}

void f(char* str)
{
cout << "f(char* str) has been called\n";
return;
}


// main
int main(int argc, char* argv[])
{
f(NULLPTR);
return 0;
}


The expected outcome is, of course, "f(char* str) has been called". Can you get this to compile and run on XCode?

P.S. If keyword "typename" does not work, replace with "class".

bousozoku
Nov 3, 2003, 04:21 PM
I copied, pasted, compiled and got:

error: unitialized const 'NULLPTR' on the line

} NULLPTR;

ksz
Nov 3, 2003, 06:00 PM
Yup, that's the problem.

According to the C++ Standard, uninitialized const pointers are automatically initialized to 0 and will compile. The following are all legal, though I haven't checked this yet on XCode:

const char* str; // okay, but will probably error in XCode
const string* str; // ditto
const MyClass* mcp; // ditto

However, const values must be initialized explicitly:

const int x; // error, x must be given a value
const int x = 0; // okay

In the NULLPTR example, try to find a way to initialize the const. For example:

const class
{
public:
...
private:
...
} NULLPTR = 0; // this won't work because there
// is no conversion from int to "const class"

However, the following should be okay, but now we no longer have an anonymous class and a class constructor has been added. (The class is intentionally anonymous because it is not meant to be instantiated by clients.)

Reworked NULLPTR to please XCode:

const class _nullptr // no longer anonymous
{
public:
template<class T>
operator T*() const { return 0; }

template<typename C, typename T>
operator T C::*() const { return 0; }

// this constructor will allow conversion from int to _nullptr
// and allow the const class initialization below.
_nullptr( int ) { }

private:
void operator&() const;

} NULLPTR = 0;


A couple of other issues with XCode:

1. One nice feature is the ability to selectively enable different categories of warnings. For example, your code can be checked against several "Effective C++" coding guidelines. However, turn this option on and try to compile. Error.

2. A minor issue: after dragging and dropping text from one place in your code to another, the cursor remains an arrow until the window is repainted. On the cool side, your selected text comes along for the drag-ride, rather than just the cursor point.


XCode looks like a very good start, but its "1.0"-ness shows every now and then. The "Intelli-Sense" implementation is very promising but less refined than Microsoft's -- too many function alternatives are sometimes displayed, some of which are simply inscrutable.

bousozoku
Nov 3, 2003, 09:41 PM
I think you'll find that the gcc standard compliance is a little on the light side--always.

I believe that ISO C90 is fully supported but C99 is not. The ISO C++ standard is probably partly supported but always remember that the standards often leave implementation details to the compiler writers and they can vary greatly from one implementation to another.

You can check the details at this URL: http://www.gnu.org/software/gcc/gcc.html

ksz
Nov 4, 2003, 03:46 AM
XCode provides the following "C Language Standards" in the GNU C/OBJ C compiler settings pane:

ANSI-C
C89
GNU89
C99
GNU99

However, with the exception of ANSI-C, these are all C, not C++ standards. Attempts to use them will result in a warning such as the following if C99 is selected:

"-std=c99" is valid for C/ObjC but not for C++

However, the C++ standard is evolving and, as you've pointed out, not all compilers implement the same version of the standard or even implement the standard fully. The standards document is, unfortunately, dense and extensive - but precise and thorough.

As a follow-up to the issue of const initialization, XCode does in fact allow uninitialized const pointers:

const int* intp; // okay
const char* charp; // okay

However, NULLPTR is of type "const class" which is not a pointer. XCode is therefore consistent in allowing uninitialized const pointers, but rejecting uninitialized const scalars. It simply does not differentiate between simple scalars such as int, double, float, etc., and complex scalars such as classes and structs.

All of this brings up another thought: C++ is just too complicated. It can be a challenge to learn-- and of course rewarding once you've learned it. But the promise of OO -- reduced cost of maintenance, reduced learning curve for new developers, extensibility, reusability, testability, etc. -- are sometimes lost amid the difficulty of getting a team to use it properly and to be mindful of the many pitfalls (i.e. design errors, omissions, oversights).

Java and C# (or more properly, .NET) are promoting a different view: component centric development rather than object centric. The promise of OO might finally be realized. Object-centric development gave us COM/DCOM/ATL/CORBA along with DLL Hell and obscure resource leaks. Managed environments such as the .NET CLR or the Java Runtime appear to be a more holistic solution to the fundamental problem of developing quality software efficiently and deploying it with equal success.

Apple's preference for Objective C over C++ stems from decisions made long ago by NeXT, but given a choice today they might still opt for Objective C.

bousozoku
Nov 4, 2003, 10:14 AM
Brad Cox did a fine job with Objective-C. There are two other programming languages which share its idealism: Smalltalk, which is older, and Java.

It's possible that NeXT would have gone with Smalltalk as IBM did, simply because of the productivity. There were few other object-oriented languages at the time. Had NeXT been born in the mid 1990s instead of 10 years earlier, they'd probably have chosen Java.

Watching it go by, I'm still not sure why people chose C++. Perhaps, it was the similarity to Pascal with the . and -> operators replacing . and ^ or just that Objective-C's [] operator made people sick in the same way they were when they wrote LISP with all the !@#$ parentheses.

I guess the only way to make certain that gcc follows the rules more closely is to become part of the team and fix the compilers. Of course, what's the advantage? MetroWerks and Borland write standards-based compilers but MS writes rubbish.

whooleytoo
Nov 4, 2003, 10:51 AM
Originally posted by bousozoku
Brad Cox did a fine job with Objective-C. There are two other programming languages which share its idealism: Smalltalk, which is older, and Java.


Ok, I wouldn't normally bring up programming issues here, but am I the only one who finds Obj-C/Cocoa quite difficult to pick up?? (And I've done commerical development on Mac and PC in C, C++, Pascal (Delphi), Powerscript (Power Builder), Basic (VB), and I'm fairly familiar with Fortan, and assembly (PPC, 680x0, x86)).

In fact, the only development environments I've struggled with are Prolog (which, in the language landscape, is in the 'Here Be Dragons' territory!) and Objective C. It just seems to be very verbose and tedious for simple operations. Plus, IB and PB as separate apps lack the ease of integration of an all-in-one package like Delphi or PowerBuilder.

Compare appending two strings in both languages:
Obj-C
NSString* first;
NSString* second;
NSString* third ;
.
.
first = [[NSString alloc] initWithString: @"Hello"] ;
second = [[NSString alloc] initWithString: @"World"] ;
.
.
third = [[NSString alloc] initWithString: [first stringByAppendingString: second]] ;

In C++
string first ;
string second ;
string third ;
.
.
first = "Hello" ;
second = "World" ;
.
.
third = first + second ;

Certainly, it's a very powerful development environment, but it has one of the steepest learning curves (IME!)

Mike.

ksz
Nov 4, 2003, 12:47 PM
Originally posted by bousozoku
I guess the only way to make certain that gcc follows the rules more closely is to become part of the team and fix the compilers. Of course, what's the advantage?
Apple's engineers provide feedback and suggestions to GNU. It is not unrealistic to think they might also be contributing both code and bug fixes a la Safari. Taking from the Open Source community and contributing back to it is not a bad business model. However, it does not really provide a competitive differentiation of your product. This might be okay because Apple does not market the Macintosh on the basis of its compiler. However, software is becoming more sophisticated (particularly vertical market s/w) and it is getting more expensive to develop, debug, and deploy.

Whatever one thinks of Microsoft personally, the .NET Framework is a small revolution in software development. The basic ideas (listed below) are not new, but they have been assembled into a cohesive framework that is very practical and addresses many of the core problems in client-server or multi-tier programming. The basic ideas are:

1. Language independence leading to binary reuse of components.
2. Runtime management including runtime security, JIT compiling, and garbage collection (memory management).
3. Location transparency or remoting.
4. Versioned assemblies; secure and strongly-named assemblies.
5. Concurrency management.
6. Simplified OO development language -- C# -- a streamlined version of C++.

Microsoft wants to standardize various component technologies in .NET such as the common language runtime and C#. These have been taken up by the ISO:

ISO C# documentation:
http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=36768&ICS1=35&ICS2=60&ICS3=

ISO CLI (common language infrastructure) documentation:
http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=36769&ICS1=35&ICS2=60&ICS3=

Apple is promoting the use of standards-based development tools and technologies. Perhaps this is something they ought to consider.

Originally posted by whooleytoo
Ok, I wouldn't normally bring up programming issues here, but am I the only one who finds Obj-C/Cocoa quite difficult to pick up??
As a recent switcher I am not familiar with Mac programming or ObjC. The string concatenation example in ObjC does look horrible, while the same thing in C++ looks beautiful... However, this is a simple use of C++. It can get worse. A lot worse.

C++ has an abundance of features and other features to allow the primary features to be applied consistently. And there is code the compiler generates for you. Forget to write a copy constructor? No problem, the compiler will do it for you. Forget to write a type conversion operator. The compiler will try to find an indirect conversion that works. None of this is really a bad thing, but it requires the programmer to go through the learning curve well. It is harder to become a C++ expert than to become a C expert.

However, the programming language we use is only one piece of the software development and deployment process. Rapid application development hinges on being able to reuse binary components; i.e., to develop applications from Lego blocks. This is where XCode and the GNU compiler tools stop short (referring to the 6 item list above).

whooleytoo
Nov 4, 2003, 01:26 PM
Originally posted by ksz
However, the programming language we use is only one piece of the software development and deployment process. Rapid application development hinges on being able to reuse binary components; i.e., to develop applications from Lego blocks. This is where XCode and the GNU compiler tools stop short (referring to the 6 item list above).

When you talk about binary components, do you mean like OpenDoc objects (which I thought were way ahead of their time) or akin to OCXs on Windows?

I'm actually intrigued by IBPalettes, which I suppose are the closest thing you can get to an OCX? It's surprising more developers haven't availed of the opportunity to plug into Apple's dev tools.

Mike.

ksz
Nov 4, 2003, 05:11 PM
Originally posted by whooleytoo
When you talk about binary components, do you mean like OpenDoc objects (which I thought were way ahead of their time) or akin to OCXs on Windows?
OpenDoc, OCX/COM, CORBA all facilitate the development of components. The basic premise for a component is simply the separation of interface from implementation. Provide clients a well-defined and hopefully immutable interface and let the implementation appear to your clients to be a black box.

However, there is more involved in making component use and reuse practical and productive. The first 5 of the 6 items in the previous list need to be addressed.

I don't know how much of this ancillary infrastructure was provided by OpenDoc, but if much of it was then Apple was really on to something. However, it seems to me that OpenDoc was not really targeted for N-tier application development; it was designed primarily for rich interaction between applications running on the same machine -- object linking and embedding. In this model, applications remain separate entities, but sections of their open documents (hence the name) can be imported into other cooperating applications and treated "natively".

The UNIX foundation of OS X makes it more compelling now to develop something akin to .NET that facilitates component development and deployment on one or more tiers. With XServe, Apple is targeting N-tier software markets but relying primarily on web servers to provide the requisite plumbing. However, not all N-tier systems can be developed around a web server, and in fact many are not. In summary, there are 3 problems here:

1. Provide a means to build applications rapidly by making component development and reuse practical (preferably even across language barriers).

2. Provide a means to deploy components and applications built from them in a safe and version-tight manner.

3. Provide a means for scalability to N-tiers.

ksz
Nov 4, 2003, 05:23 PM
On second thought OpenDoc was about creating a document-centric model and getting away from application-centrism. A document was a tabula rasa into which any application could contribute something of value - a chart from A, a table from B, a spreadsheet from C, a video clip from D, overall page formatting provided by E, spell checking courtesy of F, fancy typesetting from G, etc.

whooleytoo
Nov 4, 2003, 06:19 PM
Originally posted by ksz
On second thought OpenDoc was about creating a document-centric model and getting away from application-centrism. A document was a tabula rasa into which any application could contribute something of value - a chart from A, a table from B, a spreadsheet from C, a video clip from D, overall page formatting provided by E, spell checking courtesy of F, fancy typesetting from G, etc.

Exactly. Instead of object re-use at the developer level, it was object re-use at the user level. Effectively, the user was creating a custom application for each document, though to the user it just appeared like they were adding elements to a complex document.

Mike.

bousozoku
Nov 4, 2003, 09:13 PM
Originally posted by whooleytoo
Ok, I wouldn't normally bring up programming issues here, but am I the only one who finds Obj-C/Cocoa quite difficult to pick up?? (And I've done commerical development on Mac and PC in C, C++, Pascal (Delphi), Powerscript (Power Builder), Basic (VB), and I'm fairly familiar with Fortan, and assembly (PPC, 680x0, x86)).
...

I've coded in many of those languages/environments and a few more also. When I first approached Objective-C, it gave me a few fits. I had already done production work with C++, so it didn't seem consistent with that environment or Borland Pascal or Apple Object-Pascal either. Those all followed the hybrid approach.

Since I started, I went back to 1980s BYTE articles on Objective-C, taken two Java classes, and read more on Smalltalk. What Objective-C lacks in convenience is given in consistency between compile time and run time.