Another Code Sample for Crituque

  • Thread starter Steven T. Hatton
  • Start date
S

Steven T. Hatton

The short sample program listed below has some features that I find to be
bad style. In particular, they fail to communicate the connection between
names used in this program and the location in which they are declared and
or defined. I'd like to know if there are any features of this code you
believe represents bad programming technique. How would the feature be
better implemented?

/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
* Please visit the following url for the complete license statement:


http://cvs.apache.org/viewcvs.cgi/x...ment/CreateDOMDocument.cpp?rev=1.18&view=auto
*/

/*
* $Id: CreateDOMDocument.cpp,v 1.18 2003/12/10 23:48:53 neilg Exp $
*/

/*
* This sample illustrates how you can create a DOM tree in memory.
* It then prints the count of elements in the tree.
*/


//
---------------------------------------------------------------------------
// Includes
//
---------------------------------------------------------------------------
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#if defined(XERCES_NEW_IOSTREAMS)
#include <iostream>
#else
#include <iostream.h>
#endif

XERCES_CPP_NAMESPACE_USE

//
---------------------------------------------------------------------------
// This is a simple class that lets us do easy (though not terribly
efficient)
// trancoding of char* data to XMLCh data.
//
---------------------------------------------------------------------------
class XStr
{
public :
//
-----------------------------------------------------------------------
// Constructors and Destructor
//
-----------------------------------------------------------------------
XStr(const char* const toTranscode)
{
// Call the private transcoding method
fUnicodeForm = XMLString::transcode(toTranscode);
}

~XStr()
{
XMLString::release(&fUnicodeForm);
}


//
-----------------------------------------------------------------------
// Getter methods
//
-----------------------------------------------------------------------
const XMLCh* unicodeForm() const
{
return fUnicodeForm;
}

private :
//
-----------------------------------------------------------------------
// Private data members
//
// fUnicodeForm
// This is the Unicode XMLCh format of the string.
//
-----------------------------------------------------------------------
XMLCh* fUnicodeForm;
};

#define X(str) XStr(str).unicodeForm()


//
---------------------------------------------------------------------------
// main
//
---------------------------------------------------------------------------

int main(int argC, char* argV[])
{
// Initialize the XML4C2 system.
try
{
XMLPlatformUtils::Initialize();
}

catch(const XMLException& toCatch)
{
char *pMsg = XMLString::transcode(toCatch.getMessage());
XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization
\n"
<< " Exception message:"
<< pMsg;
XMLString::release(&pMsg);
return 1;
}

// Watch for special case help request
int errorCode = 0;
if (argC > 1)
{
XERCES_STD_QUALIFIER cout << "\nUsage:\n"
" CreateDOMDocument\n\n"
"This program creates a new DOM document from scratch in
memory.\n"
"It then prints the count of elements in the tree.\n"
<< XERCES_STD_QUALIFIER endl;
errorCode = 1;
}
if(errorCode) {
XMLPlatformUtils::Terminate();
return errorCode;
}

{
// Nest entire test in an inner block.
// The tree we create below is the same that the XercesDOMParser
would
// have created, except that no whitespace text nodes would be
created.

// <company>
// <product>Xerces-C</product>
// <category idea='great'>XML Parsing Tools</category>
// <developedBy>Apache Software Foundation</developedBy>
// </company>

DOMImplementation* impl =
DOMImplementationRegistry::getDOMImplementation(X("Core"));

if (impl != NULL)
{
try
{
DOMDocument* doc = impl->createDocument(
0, // root element namespace
URI.
X("company"), // root element name
0); // document type object
(DTD).

DOMElement* rootElem = doc->getDocumentElement();

DOMElement* prodElem = doc->createElement(X("product"));
rootElem->appendChild(prodElem);

DOMText* prodDataVal = doc->createTextNode(X("Xerces-C"));
prodElem->appendChild(prodDataVal);

DOMElement* catElem = doc->createElement(X("category"));
rootElem->appendChild(catElem);

catElem->setAttribute(X("idea"), X("great"));

DOMText* catDataVal = doc->createTextNode(X("XML Parsing
Tools"));
catElem->appendChild(catDataVal);

DOMElement* devByElem =
doc->createElement(X("developedBy"));
rootElem->appendChild(devByElem);

DOMText* devByDataVal = doc->createTextNode(X("Apache
Software Foundation"));
devByElem->appendChild(devByDataVal);

//
// Now count the number of elements in the above DOM tree.
//

unsigned int elementCount =
doc->getElementsByTagName(X("*"))->getLength();
XERCES_STD_QUALIFIER cout << "The tree just created contains:
" << elementCount
<< " elements." << XERCES_STD_QUALIFIER endl;

doc->release();
}

catch (const DOMException& e)
{
XERCES_STD_QUALIFIER cerr << "DOMException code is: " <<
e.code << XERCES_STD_QUALIFIER endl;
errorCode = 2;
}
catch (...)
{
XERCES_STD_QUALIFIER cerr << "An error occurred creating the
document" << XERCES_STD_QUALIFIER endl;
errorCode = 3;
}
} // (inpl != NULL)
else
{
XERCES_STD_QUALIFIER cerr << "Requested implementation is not
supported" << XERCES_STD_QUALIFIER endl;
errorCode = 4;
}
}

XMLPlatformUtils::Terminate();
return errorCode;
}
 
S

Steven T. Hatton

Steven said:
The short sample program listed below has some features that I find to be
bad style. In particular, they fail to communicate the connection between
names used in this program and the location in which they are declared and
or defined. I'd like to know if there are any features of this code you
believe represents bad programming technique. How would the feature be
better implemented?

/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
* Please visit the following url for the complete license statement:


http://cvs.apache.org/viewcvs.cgi/x...ment/CreateDOMDocument.cpp?rev=1.18&view=auto
---------------------------------------------------------------------------
// Includes
//
---------------------------------------------------------------------------
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#if defined(XERCES_NEW_IOSTREAMS)
#include <iostream>
#else
#include <iostream.h>
#endif

What is this? Is it grammatically part of C++?
XERCES_CPP_NAMESPACE_USE

//
At a second level of #inclusion I found this:

//
---------------------------------------------------------------------------
// Define namespace symbols if the compiler supports it.
//
---------------------------------------------------------------------------
#if defined(XERCES_HAS_CPP_NAMESPACE)
#define XERCES_CPP_NAMESPACE_BEGIN namespace XERCES_CPP_NAMESPACE {
#define XERCES_CPP_NAMESPACE_END }
#define XERCES_CPP_NAMESPACE_USE using namespace XERCES_CPP_NAMESPACE;
#define XERCES_CPP_NAMESPACE_QUALIFIER XERCES_CPP_NAMESPACE::

namespace XERCES_CPP_NAMESPACE { }
namespace xercesc = XERCES_CPP_NAMESPACE;
#else
#define XERCES_CPP_NAMESPACE_BEGIN
#define XERCES_CPP_NAMESPACE_END
#define XERCES_CPP_NAMESPACE_USE
#define XERCES_CPP_NAMESPACE_QUALIFIER
#endif

I find that downright depressing.


This is C programming, not C++.
 
S

Steven T. Hatton

This is from the same sample code I posted earlier. I believe the form of
the function main shown here is not specified in the Standard, and the
Standard does not require an implementation to successfully compile it. Do
you agree?

int main(int argC, char* argV[])
{}
 
R

Robert Bauck Hamar

This is from the same sample code I posted earlier. I believe the form of
the function main shown here is not specified in the Standard, and the
Standard does not require an implementation to successfully compile it. Do
you agree?

int main(int argC, char* argV[])
{}

From §3.6.1:
All implementations shall allow both of the following definitions of
main:

int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
 
R

Robert Bauck Hamar

This is from the same sample code I posted earlier. I believe the form of
the function main shown here is not specified in the Standard, and the
Standard does not require an implementation to successfully compile it. Do
you agree?

int main(int argC, char* argV[])
{}

From §3.6.1:
All implementations shall allow both of the following definitions of
main:

int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }

And I forgot:
If control reaches the end of main without encountering a return
statement, the effect is that of executing
return 0;
 
S

Steven T. Hatton

Robert said:
This is from the same sample code I posted earlier. I believe the form
of the function main shown here is not specified in the Standard, and the
Standard does not require an implementation to successfully compile it.
Do you agree?

int main(int argC, char* argV[])
{}

From §3.6.1:
All implementations shall allow both of the following definitions of
main:

int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
So I conclude that the form I presented is not specified by the standard.
 
R

Robert Bauck Hamar

Robert said:
This is from the same sample code I posted earlier. I believe the form
of the function main shown here is not specified in the Standard, and the
Standard does not require an implementation to successfully compile it.
Do you agree?

int main(int argC, char* argV[])
{}

From §3.6.1:
All implementations shall allow both of the following definitions of
main:

int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
So I conclude that the form I presented is not specified by the standard.

If you are thinking about the naming of the parameters, then I cannot
see that the standard says anything more than I just wrote. Mark that
main should not be overloaded and must return an int, but othervise it's
type is implementation defined.
 
S

Steven T. Hatton

Robert said:
Robert said:
This is from the same sample code I posted earlier. I believe the form
of the function main shown here is not specified in the Standard, and
the Standard does not require an implementation to successfully compile
it. Do you agree?

int main(int argC, char* argV[])
{}


From §3.6.1:
All implementations shall allow both of the following definitions of
main:

int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
So I conclude that the form I presented is not specified by the standard.

If you are thinking about the naming of the parameters, then I cannot
see that the standard says anything more than I just wrote. Mark that
main should not be overloaded and must return an int, but othervise it's
type is implementation defined.
Yes, the names. Do you understand the Standard to be requiring the names to
be exactly those used in the text of the Standard? I understand it to be
saying that.
 
R

Robert Bauck Hamar

Robert said:
Robert Bauck Hamar wrote:

This is from the same sample code I posted earlier. I believe the form
of the function main shown here is not specified in the Standard, and
the Standard does not require an implementation to successfully compile
it. Do you agree?

int main(int argC, char* argV[])
{}


From §3.6.1:
All implementations shall allow both of the following definitions of
main:

int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }

So I conclude that the form I presented is not specified by the standard.

If you are thinking about the naming of the parameters, then I cannot
see that the standard says anything more than I just wrote. Mark that
main should not be overloaded and must return an int, but othervise it's
type is implementation defined.
Yes, the names. Do you understand the Standard to be requiring the names to
be exactly those used in the text of the Standard? I understand it to be
saying that.

Considering §3.6.1 [basic.start.main] alone, yes. Grepping the standard
for main, I found mostly main() in examples. Two examples in §22.2.8
defined:
int main(int argc, char** argv) { /* ... */ }
I also searched for argc and argv, but i found nothing more than §3.6.1,
the same examples, and C compitability issues.
 
R

red floyd

Robert said:
Robert Bauck Hamar wrote:

Robert Bauck Hamar wrote:


This is from the same sample code I posted earlier. I believe the form
of the function main shown here is not specified in the Standard, and
the Standard does not require an implementation to successfully compile
it. Do you agree?

int main(int argC, char* argV[])
{}


From §3.6.1:
All implementations shall allow both of the following definitions of
main:

int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }


So I conclude that the form I presented is not specified by the standard.

If you are thinking about the naming of the parameters, then I cannot
see that the standard says anything more than I just wrote. Mark that
main should not be overloaded and must return an int, but othervise it's
type is implementation defined.

Yes, the names. Do you understand the Standard to be requiring the names to
be exactly those used in the text of the Standard? I understand it to be
saying that.


Considering §3.6.1 [basic.start.main] alone, yes. Grepping the standard
for main, I found mostly main() in examples. Two examples in §22.2.8
defined:
int main(int argc, char** argv) { /* ... */ }
I also searched for argc and argv, but i found nothing more than §3.6.1,
the same examples, and C compitability issues.

I don't know... I've also compiled (but don't know if it's complaint)

int main(int, char*[])
{
}
 
R

Robert Bauck Hamar

Robert said:
Yes, the names. Do you understand the Standard to be requiring the names to
be exactly those used in the text of the Standard? I understand it to be
saying that.

Considering §3.6.1 [basic.start.main] alone, yes. Grepping the standard
for main, I found mostly main() in examples. Two examples in §22.2.8
defined:
int main(int argc, char** argv) { /* ... */ }
I also searched for argc and argv, but i found nothing more than §3.6.1,
the same examples, and C compitability issues.

I don't know... I've also compiled (but don't know if it's complaint)

int main(int, char*[])
{
}

Of course you have.
$ cat example.cc
#include <iostream>

int main(int, char **, char *e[])
{
for (; *e; ++e)
std::cout << *e << std::endl;
}
$ g++ -ansi -Wall example.cc
$

As you can see. This compiles without a warning on my compiler, and this
little program will print out my environment variables. A conforming
compiler is not required to compile this, but it is explicitly allowed
to.
 
S

Steven T. Hatton

Robert Bauck Hamar wrote:

Of course you have.
$ cat example.cc
#include <iostream>

int main(int, char **, char *e[])
{
for (; *e; ++e)
std::cout << *e << std::endl;
}
$ g++ -ansi -Wall example.cc
$

Interesting bit of hackery.
As you can see. This compiles without a warning on my compiler, and this
little program will print out my environment variables. A conforming
compiler is not required to compile this, but it is explicitly allowed
to.

"Explicitly"? That seems a bit strong. How do you argue that it is explicit
about this? The undefined catch-all?
 
T

tom_usenet

Robert Bauck Hamar wrote:

Of course you have.
$ cat example.cc
#include <iostream>

int main(int, char **, char *e[])
{
for (; *e; ++e)
std::cout << *e << std::endl;
}
$ g++ -ansi -Wall example.cc
$

Interesting bit of hackery.
As you can see. This compiles without a warning on my compiler, and this
little program will print out my environment variables. A conforming
compiler is not required to compile this, but it is explicitly allowed
to.

"Explicitly"? That seems a bit strong. How do you argue that it is explicit
about this? The undefined catch-all?

No, the standard says that the type of main is implementation defined,
except that it must return int. It then goes on to say that int main()
and int main(int argc, char* argv[]) *must* be provided by all
implementations. So the above is just an implementation defined main
signature.

As for the naming of variables, I really don't think that the intent
of the standard is to ban naming the first and second parameter of
main whatever you want, but simply to give the required signatures of
main that should be available. The wording of the standard talks about
"allowing the following definitions of main". My understanding is that
it refers to the signatures, not the literal characters shown. So I
think that

int main(int const bubbles, char** fun)
{
}

is fine (note that top-level const in parameter types is not part of
the function signature).

Tom
 
S

Steven T. Hatton

tom_usenet said:
Robert Bauck Hamar wrote:

Of course you have.
$ cat example.cc
#include <iostream>

int main(int, char **, char *e[])
{
for (; *e; ++e)
std::cout << *e << std::endl;
}
$ g++ -ansi -Wall example.cc
$

Interesting bit of hackery.
As you can see. This compiles without a warning on my compiler, and this
little program will print out my environment variables. A conforming
compiler is not required to compile this, but it is explicitly allowed
to.

"Explicitly"? That seems a bit strong. How do you argue that it is
explicit about this? The undefined catch-all?

No, the standard says that the type of main is implementation defined,
except that it must return int. It then goes on to say that int main()
and int main(int argc, char* argv[]) *must* be provided by all
implementations. So the above is just an implementation defined main
signature.

As for the naming of variables, I really don't think that the intent
of the standard is to ban naming the first and second parameter of
main whatever you want, but simply to give the required signatures of
main that should be available. The wording of the standard talks about
"allowing the following definitions of main". My understanding is that
it refers to the signatures, not the literal characters shown. So I
think that

int main(int const bubbles, char** fun)
{
}

is fine (note that top-level const in parameter types is not part of
the function signature).

Tom

I honestly have to say, I don't know what is intended by the use of the word
"type" in: "It shall have a return type of type int, but otherwise its type
is implementation-defined."

It seems inconsistent to suggest that has to do with signature, since, after
it states the above, the Standard goes on to impose requirements on the
signature of main.
 
R

Robert Bauck Hamar

I believe you are right about the intent. In §6.1.7 of 'The C++
Programming Language' Bjarne Stroustrup writes:

'A program starts by calling /main/(). When this is done, /main/() is
given two arguments specifying the number of arguments, usually called
/argc/, and an array of arguments, usually called /argv/.'

I think that Bjarne Stroustrup's use of the word 'usually' clearly
states the intent. I find it hard to believe that this is a real world
problem, as every compiler vendor I've seen will accept different naming
of the arguments.

My problem is: The standard _could_ have used the word 'type' or the
word 'signature' to claim it's intent, but it didn't. It also makes it
possible for an implementation to not generate a callable function for
main. That is why I
can't formally say that an implementation is required to handle
arguments with other names.
I honestly have to say, I don't know what is intended by the use of the word
"type" in: "It shall have a return type of type int, but otherwise its type
is implementation-defined."

The word type is carefully defined by the standard.
 
S

Steven T. Hatton

Steven said:
The short sample program listed below has some features that I find to be
bad style. In particular, they fail to communicate the connection between
names used in this program and the location in which they are declared and
or defined. I'd like to know if there are any features of this code you
believe represents bad programming technique. How would the feature be
better implemented?

/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
* Please visit the following url for the complete license statement:


http://cvs.apache.org/viewcvs.cgi/x...ment/CreateDOMDocument.cpp?rev=1.18&view=auto
---------------------------------------------------------------------------
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/dom/DOM.hpp>
#if defined(XERCES_NEW_IOSTREAMS)
#include <iostream>
#else
#include <iostream.h>
#endif

XERCES_CPP_NAMESPACE_USE

Before anybody flames me for posting this, please consider the fact that I
have not written any significant amount of Java code in months, and have
dedicated most of my waking hours to learning and working with C++.

Strustrup has long advocated the abolishon of the preprocessor as a part of
C++. He recently wrote: "The hardest part of the preprocessor to do without
is #include. If you don't have an alternative for that - and we don't have
an acceptably complete alternative..."

The following is intended to address that deficincy of C++.

The listing below is from a sample of Java code written for the Java
implementation of Xerces, more or less comperable to the C++ listed above:


http://cvs.apache.org/viewcvs.cgi/xml-xerces/java/samples/dom/Counter.java?rev=1.10&view=markup
/******************************/

package dom;
import java.io.PrintWriter;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/******************************/

The preceeding statements could be expressed analogously in C++ as follows:
namespace dom{
using org::w3c::dom::Document;
using org::w3c::dom::NamedNodeMap;
using org::w3c::dom::Node;
using org::w3c::dom::Text;
using org::xml::sax::SAXException;
using org::xml::sax::SAXParseException;
}

Unfortunately, that is not sufficient to accomplish the same ends in C++.
In terms of the language, it is equally specific. Unfortunately, the C++
standard does not require the implementation to resolve the location of the
named classes for us. Another way of saying this is that C++ lacks the
power to provide this valuable functionality. The approach used in Java is
hardly an earthshattering innovation. The designers simply chose to
exploit a data storage and retrieval mechanism they had good reason to
believe would be available on virtually any platform other than embedded
systems(where Java was born). That mechanism is called a file system.

I am not suggesting exactly the same mechanism could, or should be used for
C++. I am saying C++ should have mechanism that works similarly to the one
demonstrated above. This approach is hardly unique to Java. It is also
used by Mathematica to name and locate packages.

There is an additional consideration involved which has to be addressed in
order for C++ to provide the kind of support I'm suggesting.

Legend has it that what Gosling did when he designed Java is to look at C++
and other programming languages C, SmallTalk and Lisp, in particular and
tried to identify the features that increased productivity, and which ones
introduced pitfalls. One of the ideas Gosling seems to have borrowed from
Stroustrup (as distinct from C++) is the idea that every class should have
an interface, and an implementation. In this context I do not mean
interface in the sense of the Java language feature called interface in the
fromal specification.

Gosling seems to have rejected the notion that a programmer should manually
create the interface, as Stroustrup suggests we should do in header files.
Instead Gosling created a mechanism to extract the interface from the
implementation. That mechanism is implemented by the javap command. For
example, the following corresponds in an obvious way to declarations that
would go in a traditional C++ header file:

$ javap java.io.PrintWriter
Compiled from "PrintWriter.java"
public class java.io.PrintWriter extends java.io.Writer{
protected java.io.Writer out;
public void close();
public void flush();
public void println();
protected void setError();
public boolean checkError();
public void print(char);
public void println(char);
public void print(double);
public void println(double);
public void print(float);
public void println(float);
public void print(int);
public void println(int);
public void write(int);
public void print(long);
public void println(long);
public void print(boolean);
public void println(boolean);
public void print(char[]);
public void println(char[]);
public void write(char[]);
public void write(char[],int,int);
public java.io.PrintWriter(java.io_OutputStream);
public java.io.PrintWriter(java.io_OutputStream,boolean);
public java.io.PrintWriter(java.io.Writer);
public java.io.PrintWriter(java.io.Writer,boolean);
public void print(java.lang.Object);
public void println(java.lang.Object);
public void print(java.lang.String);
public void println(java.lang.String);
public void write(java.lang.String);
public void write(java.lang.String,int,int);
}

If the notion of interface - as used in reference to what goes in a header
file - were formalized in C++, it would facilitate the specification of a
mechanism similar to the one used by Java. This would be a huge step
toward obviating the preprocessor.
 
S

Steven T. Hatton

Robert said:
I believe you are right about the intent.

I will point out that the Standard uses the term /definitions/ in:

All implementations shall allow both of the following definitions of main:

int main() { /* ... */ } and int main(int argc, char* argv[]) { /* ... */ }

In function /declarations/ that are not definitions the names of parameters
are limited to the scope of the parameter declaration clause. In function
definitions they are used to define an identifier whose scope is the
function body. This does not prove that the parameter name participates in
the definition of the function, per se, but it seems to suggest it.
In §6.1.7 of 'The C++ Programming Language' Bjarne Stroustrup writes:

'A program starts by calling /main/(). When this is done, /main/() is
given two arguments specifying the number of arguments, usually called
/argc/, and an array of arguments, usually called /argv/.'

I think that Bjarne Stroustrup's use of the word 'usually' clearly
states the intent.

*His* intent in a textbook. What the standard actually specifies, and what
is written in a textbook are not of the same nature. He is not the only
author of the standard, nor is his textbook the authority defining the C++
programming language. The textbook is intended to teach people to use the
language, and thus is likely to focus on how the language is actually
implemented, not how the standard specifies it should be implemented.
I find it hard to believe that this is a real world problem, as every
compiler vendor I've seen will accept different naming of the arguments.

It was just a curiosity I had. I noticed the discrepancy, and I wasn't
really sure what to make of what the Standard said when I looked it up. I
will caution against using the behavior of compilers as the definitive test
of language conformance. I posted some code to this newsgroup that wasn't
compiling for me. People told me to go tell the compiler implementor to
fix the compiler, because it compiled with 'their' compiler. I went to the
compiler implementor and showed them the problem. They told me the problem
was that the program did not conform to the standard, and cited clause and
paragraph. It was then suggested I contact the original programmer to let
him know there was a problem with his code. So I did. The message began
with 'Dr. Stroustrup, ...'
My problem is: The standard _could_ have used the word 'type' or the
word 'signature' to claim it's intent, but it didn't. It also makes it
possible for an implementation to not generate a callable function for
main.

I'm not sure I follow. Are you referring to hosted implementations?
That is why I can't formally say that an implementation is required to
handle arguments with other names.

The word type is carefully defined by the standard.

What the standard says seems contrary to how it is used in the statement. As
for the definition of the word type, I don't see anywhere that it is
defined without reference to some specific usage.
 
T

tom_usenet

I honestly have to say, I don't know what is intended by the use of the word
"type" in: "It shall have a return type of type int, but otherwise its type
is implementation-defined."

"function type". That includes the return type and parameter types,
but it's saying that implementation defined main functions don't have
the freedom to return anything but int - IOW, the freedom is in the
parameter types only.
It seems inconsistent to suggest that has to do with signature, since, after
it states the above, the Standard goes on to impose requirements on the
signature of main.

But these requirements are just that implementations must *at least*
allow those two definitions of main. They can allow any others that
they want to, just so long as they return int. Is that not clear?

Tom
 
T

tom_usenet

Robert said:
I believe you are right about the intent.

I will point out that the Standard uses the term /definitions/ in:

All implementations shall allow both of the following definitions of main:

int main() { /* ... */ } and int main(int argc, char* argv[]) { /* ... */ }

In function /declarations/ that are not definitions the names of parameters
are limited to the scope of the parameter declaration clause. In function
definitions they are used to define an identifier whose scope is the
function body. This does not prove that the parameter name participates in
the definition of the function, per se, but it seems to suggest it.

If you read the text literally as you are doing, the only conforming
programs those that do nothing, and whose main functions contain just
/* ... */! I don't think you are supposed to take it quite so
literally. I am sure the intent only refers to the types of the
functions, and that, in effect, an implementation must provide these
implicit declarations for main:

int main();
int main(int, char**);
What the standard says seems contrary to how it is used in the statement. As
for the definition of the word type, I don't see anywhere that it is
defined without reference to some specific usage.

"type" isn't defined since it is a standard computing term. However,
"static type", "dynamic type", "function type", etc. are all defined
one way or another.

Tom
 
J

JKop

The textbook is intended to teach people to use the language, and thus
is likely to focus on how the language is actually implemented, not how
the standard specifies it should be implemented.


Wouldn't it be great if they were the same thing



-JKop
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top