Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

() and no ()

2 views
Skip to first unread message

Michael Novello

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
Does anyone know the difference between using () in a function call and not
using ()?

Thanks! Michael

Larry Brasfield

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
Michael Novello wrote in message <36b8f...@hoh.olympus.net>...

>Does anyone know the difference between using () in a function call and not
>using ()?

I presume you mean the outermost parenthesis surrounding
the arguments. There are a few cases to consider:

1. someFunction();
That could call a function which takes no arguments or
provides defaults for all its arguments.

2. someFunction;
That is not a function call. It is a silly expression yielding
the address of a function with which nothing is done.

3. anotherFunction( actualArgument1, actualArgument2 );
That could call a function with provided arguments.

4. anotherFunction actualArgument1, actualArgument2 ;
That would be a syntax error in most cases unless those
identifiers are #define'd to become something else.

>Thanks! Michael

The bottom line is that a parenthesized (possibly empty)
argument list can be thought of as the invoke operator
in C and C++. The difference between using or not using
() is the difference between calling and not calling.

--Larry Brasfield
Above opinions may be mine alone.
(Humans may reply at unundered larry_br@sea_net.com )


David A Henry

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
On Thu, 4 Feb 1999, Larry Brasfield wrote:
> The bottom line is that a parenthesized (possibly empty)
> argument list can be thought of as the invoke operator
> in C and C++. The difference between using or not using
> () is the difference between calling and not calling.

Yeah, I thought he might mean for constructors. When you call a void
constructor you must (?) leave off the "()" or it will treat it as a
function declaration.

int main(void)
{
CFoo foo;
// not: CFoo foo(); new foo();

return 0;
}

Which makes a bit of sense!? I have heard it explained that it would be
treated as a function declaration. But I think it is kinda
counter-intuitive to leave the parenthesis off!?

David A Henry
dhenry_bigfoot_com
http://www.bigfoot.com/~dhenry


jim.h...@leitch.com

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
In article <Pine.SUN.3.96.990204134044.25361B-100000@caris>,

David A Henry <he...@universal.ca> wrote:
> On Thu, 4 Feb 1999, Larry Brasfield wrote:
> > The bottom line is that a parenthesized (possibly empty)
> > argument list can be thought of as the invoke operator
> > in C and C++. The difference between using or not using
> > () is the difference between calling and not calling.
>
> Yeah, I thought he might mean for constructors. When you call a void
> constructor you must (?) leave off the "()" or it will treat it as a
> function declaration.
>
> int main(void)
> {
> CFoo foo;
> // not: CFoo foo(); new foo();
'new foo();' is acceptable (if possibly misleading), because there is no
ambiguity. You are using a reserved keyword "new", so you cannot possibly be
referring to any user-defined type, nor can you be declaring a function.

>
> return 0;
> }
>
> Which makes a bit of sense!? I have heard it explained that it would be
> treated as a function declaration. But I think it is kinda
> counter-intuitive to leave the parenthesis off!?

When the compiler sees "CFoo foo();" it has to decide what you mean - do you
mean to create an object of type CFoo, or do you mean to declare a function
called 'foo' which takes no parameters and returns a CFoo?

"When in doubt, do as ints do" is a maxim you should remember - no compiler
will have any doubt what you mean by "int foo();" - you are declaring a
function. Do you want the compiler to, instead, treat it as a declaration of
an int variable that calls int::int()? I don't think so.

Since you cannot take the address of a constructor, nor can you call it
directly, the required behaviour (assume it's a function declaration) makes
sense to me.

Jim
Note to recruitment agencies: I will not refer my friends or colleagues
to you nor do I want to use your services to find me a job. I stop
reading unsolicited email as soon as I determine it is job-recruitment

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own

Larry Brasfield

unread,
Feb 8, 1999, 3:00:00 AM2/8/99
to
David A Henry wrote in message ...

>On Thu, 4 Feb 1999, Larry Brasfield wrote:
>> The bottom line is that a parenthesized (possibly empty)
>> argument list can be thought of as the invoke operator
>> in C and C++. The difference between using or not using
>> () is the difference between calling and not calling.

My above comments should be limited to
the case where a function name is (or is
not) followed by parenthesized arguments.

>Yeah, I thought he might mean for constructors. When you call a void
>constructor you must (?) leave off the "()" or it will treat it as a
>function declaration.
>
>int main(void)
>{
> CFoo foo;
> // not: CFoo foo(); new foo();
>

> return 0;
>}
>
>Which makes a bit of sense!? I have heard it explained that it would be
>treated as a function declaration. But I think it is kinda
>counter-intuitive to leave the parenthesis off!?

Yes, it is somewhat inconsistent. If a set
of N arguments can appear, it would be
conceptually simpler if the same meaning
applied when N is 0.

It would make a little more sense if you
stop thinking of that language construct
as a constructor call. I find it simpler to
think of it as either taking the default-
constructed initial value or specifying
a non-default constructed initial value,
without trying to shoehorn it into the
normal call syntax. With all the other
stuff happening, (an implicit object
passed to the constructor, and a heap
or stack allocation), I cannot think of
it as a mere call. Since it is more than
a mere call, there is no advantage to
treating it like one conceptually.

Alex Vinokur

unread,
Feb 15, 1999, 3:00:00 AM2/15/99
to
In article <79d09p$6li$1...@nnrp1.dejanews.com>,
jim.h...@leitch.com wrote:

[snip]


> When the compiler sees "CFoo foo();" it has to decide what you mean - do you
> mean to create an object of type CFoo, or do you mean to declare a function
> called 'foo' which takes no parameters and returns a CFoo?

[snip]


Yes.

But what causes it?

There is the difference between declaration and calling
functions with arguments and without arguments.


######################################
1. Function with arguments (example)
Declaration : TYPE foo1 (int arg), i.e. TYPE foo1 (<type>)
Calling : foo1 (123), i.e. foo1 (<value>)

2. Function without arguments (example)
Declaration : TYPE foo2 (), i.e. TYPE foo2 ()
TYPE foo2 (void), i.e. TYPE foo2 (<type>); not mandatory
Calling : foo2 (), i.e. foo2 ()


######################################
Let's create some class.
class BBB
{
public :
BBB () {}
BBB (int dummy) {}
~BBB () {}
};


######################################
=====================================
A. Now about function with arguments :

BBB b1 (123);
// C language cannot do parsing it, so C++ does it.
// b1 is object of the BBB class
// ^^^^^^

BBB b2 (string arg); // C language already knows how to do parsing it. // b2
is type : a function called b2 with one string-argument and returns a BBB //
^^^^ ^^^^^^^^


=====================================
B. But what happens with function without arguments :

BBB b3 ();
// C language already (!) knows how to do parsing it.
// b3 is type : a function called b3 without arguments and returns a BBB
// ^^^^ ^^^^^^^^
// Why can C do parsing it?
// Because TYPE foo2 (void) isn't mandatory declaration syntax.
// ^^^^^^^^^^^****^


=====================================
C. If TYPE foo2 (void) were mandatory syntax of declaration
^^^^^^^^^^^****^
we would be able to write as following :


BBB b4 ();
// C language couldn't do parsing it, so C++ would do it.
// b4 would be object of the BBB class
// ^^^^^^

BBB b5 (void);
// C language could do parsing it.
// b5 would be type : a function called b5 without arguments and returns a BBB
// ^^^^ ^^^^^^^^


##########################################

Alex

jim.h...@leitch.com

unread,
Feb 15, 1999, 3:00:00 AM2/15/99
to
In article <7a8veb$7u7$1...@nnrp1.dejanews.com>,

Alex Vinokur <alexande...@telrad.co.il> wrote:
> In article <79d09p$6li$1...@nnrp1.dejanews.com>,
> jim.h...@leitch.com wrote:
>
> [snip]
> > When the compiler sees "CFoo foo();" it has to decide what you mean - do you
> > mean to create an object of type CFoo, or do you mean to declare a function
> > called 'foo' which takes no parameters and returns a CFoo?
> [snip]
>
> Yes.
>
> But what causes it?
Legacy issues with C.

Consider the following line:

// struct T typedef'd elsewhere
T foo();

In C, its meaning is unambiguous - you are declaring a function which takes
no parameters and returns a struct T, simply because C has absolutely no
concept of constructors.

> There is the difference between declaration and calling
> functions with arguments and without arguments.
>
> ######################################
> 1. Function with arguments (example)
> Declaration : TYPE foo1 (int arg), i.e. TYPE foo1 (<type>)
> Calling : foo1 (123), i.e. foo1 (<value>)
>
> 2. Function without arguments (example)
> Declaration : TYPE foo2 (), i.e. TYPE foo2 ()
> TYPE foo2 (void), i.e. TYPE foo2 (<type>); not mandatory
> Calling : foo2 (), i.e. foo2 ()
>
> ######################################
> Let's create some class.
> class BBB
> {
> public :
> BBB () {}
> BBB (int dummy) {}
> ~BBB () {}
> };
>
> ######################################
> =====================================
> A. Now about function with arguments :
>
> BBB b1 (123);
> // C language cannot do parsing it, so C++ does it.
> // b1 is object of the BBB class

Yes, this is unambiguous - you cannot declare a function this way, therefore
you must be instantiating an object of type BBB.

> BBB b2 (string arg); // C language already knows how to do parsing it. // b2
> is type : a function called b2 with one string-argument and returns a BBB //

Agreed, this is also unambiguous.

> B. But what happens with function without arguments :
>
> BBB b3 ();
> // C language already (!) knows how to do parsing it.
> // b3 is type : a function called b3 without arguments and returns a BBB

Ah, but is it? Remember the rule "when in doubt, do as ints do" - if you saw:

int b3();

you would take that as a function declaration, not as a command to instantiate
an int called b3, using its default parameter (remember, you *CAN* write int()
to call the default ctor (so to speak) for ints).

> // Why can C do parsing it?
> // Because TYPE foo2 (void) isn't mandatory declaration syntax.

No, because C does not have constructors. In C, foo2() can mean only one
thing - a function called foo2. Also, in a function declaration "(void)" is
exactly the same as "()" - there is no difference in meaning.

> C. If TYPE foo2 (void) were mandatory syntax of declaration

> we would be able to write as following :
>
> BBB b4 ();
> // C language couldn't do parsing it, so C++ would do it.
>

> BBB b5 (void);
> // C language could do parsing it.
> // b5 would be type : a function called b5 without arguments and returns a BBB

Wait a minute - are you suggesting the compiler should determine from context
whether to apply C rules or C++ rules? I would vehemently oppose any such
proposition. Allowing such behaviour would introduce so many subtle bugs
it's not funny - you make one tiny, tiny change to your code and suddenly
it's no longer a C++ module, it's a C module which behaves entirely
differently and your program is completely broken and unusable, and you'll be
scratching your head wondering why. Worse, some parts of the object module
may be interpreted as C and other parts *of the same module* would be
interpreted as C++. No, thank you!!

Now, assuming you can get around that kind of problem, you have yet another
problem - currently, a parameter list of "(void)" means exactly the same as
"()". By introducing a different meaning to "(void)" you have now silently
broken many thousands of object modules which rely on "()" and "(void)" having
identical meanings.

I'll stick with the current standard, which says that if the compiler has a
choice, it's treated as a function declaration. At least the rules are
consistent!

Jim
Note to recruitment agencies: I will not refer my friends or colleagues
to you nor do I want to use your services to find me a job. I stop
reading unsolicited email as soon as I determine it is job-recruitment

-----------== Posted via Deja News, The Discussion Network ==----------

Rod Spade

unread,
Feb 15, 1999, 3:00:00 AM2/15/99
to
Picky detail: I think in C "T foo();" is the same as "T foo(...);", not
"T foo(void)" as in C++. (Of course, that's not relevant for the
argument at hand.)

Alex Vinokur

unread,
Feb 16, 1999, 3:00:00 AM2/16/99
to
Thank you very much for your analysis.

In article <7a9hnn$mbu$1...@nnrp1.dejanews.com>,
jim.h...@leitch.com wrote:

[snip]


>
> int b3();
>
> you would take that as a function declaration, not as a command to instantiate
> an int called b3, using its default parameter (remember, you *CAN* write int()
> to call the default ctor (so to speak) for ints).

Can we write int() to call the default ctor (so to speak) for ints ?

Here is the main program.
//====== BEGIN ================
#include <stl.h>
int main ()
{
int i1 ();
cout << i1 << endl;
//----------
return 0;
}
//====== END ==================


Here is the compilation result. g++ -v : gcc version egcs-2.91.57 19980901
(egcs-1.1 release) uname -a : SunOS tibamsun8 5.6 Generic_105181-09 sun4m
sparc SUNW,SPARCstation-5 //====== BEGIN ================
/var/tmp/ccKGnDHF.o: In function `main': /var/tmp/ccKGnDHF.o(.text+0x4):
undefined reference to `i1(void)' /var/tmp/ccKGnDHF.o(.text+0x8): undefined
reference to `i1(void)' collect2: ld returned 1 exit status //====== END
==================


>
> > // Why can C do parsing it?
> > // Because TYPE foo2 (void) isn't mandatory declaration syntax.
>
> No, because C does not have constructors. In C, foo2() can mean only one
> thing - a function called foo2. Also, in a function declaration "(void)" is
> exactly the same as "()" - there is no difference in meaning.
>

This is the point.
If TYPE foo2 (void) is mandatory declaration syntax,
TYPE foo2 () can't be declaration syntax,
i.e. foo2 () can't mean a function called foo2.

[snip]

>
> Wait a minute - are you suggesting the compiler should determine from context
> whether to apply C rules or C++ rules? I would vehemently oppose any such
> proposition. Allowing such behaviour would introduce so many subtle bugs
> it's not funny - you make one tiny, tiny change to your code and suddenly
> it's no longer a C++ module, it's a C module which behaves entirely
> differently and your program is completely broken and unusable, and you'll be
> scratching your head wondering why. Worse, some parts of the object module
> may be interpreted as C and other parts *of the same module* would be
> interpreted as C++. No, thank you!!

No, I'm not suggesting it.
I mean the following thing.

If C++ compiler knows how to interpret a program sentence
according to C rules, there are not C++ rules
which the compiler could interpret the same sentence according to
(there are not C++ rules competing with these C rules).

I.e. in C++ compiler the C rules are the part of the C++ rules,
and C rules are *preceding* *pure* C++ rules.
So, the compiler behavior is unambiguous and don't depend on context.

[snip]


Thanks,
Alex

jim.h...@leitch.com

unread,
Feb 16, 1999, 3:00:00 AM2/16/99
to
In article <7ab7hg$3go$1...@nnrp1.dejanews.com>,

Alex Vinokur <alexande...@telrad.co.il> wrote:
> Thank you very much for your analysis.
>
> In article <7a9hnn$mbu$1...@nnrp1.dejanews.com>,
> jim.h...@leitch.com wrote:
>
> [snip]
> >
> > int b3();
> >
> > you would take that as a function declaration, not as a command to
instantiate
> > an int called b3, using its default parameter (remember, you *CAN* write
int()
> > to call the default ctor (so to speak) for ints).
>
> Can we write int() to call the default ctor (so to speak) for ints ?
OK, maybe not so literally.
[snip]

> >
> > > // Why can C do parsing it?
> > > // Because TYPE foo2 (void) isn't mandatory declaration syntax.
> >
> > No, because C does not have constructors. In C, foo2() can mean only one
> > thing - a function called foo2. Also, in a function declaration "(void)" is
> > exactly the same as "()" - there is no difference in meaning.
> >
>
> This is the point.
> If TYPE foo2 (void) is mandatory declaration syntax,
> TYPE foo2 () can't be declaration syntax,
> i.e. foo2 () can't mean a function called foo2.

which leads directly to my second point below, which is: changing the meaning
of () will break a LOT of code.

> [snip]
>
> >
> > Wait a minute - are you suggesting the compiler should determine from
context

[snip]


> No, I'm not suggesting it.

<whew> Thank goodness :-)

> I mean the following thing.
>
> If C++ compiler knows how to interpret a program sentence
> according to C rules, there are not C++ rules
> which the compiler could interpret the same sentence according to
> (there are not C++ rules competing with these C rules).
>
> I.e. in C++ compiler the C rules are the part of the C++ rules,
> and C rules are *preceding* *pure* C++ rules.
> So, the compiler behavior is unambiguous and don't depend on context.

Even so, you're still breaking a lot of existing code. At least potentially.

Jim
Note to recruitment agencies: I will not refer my friends or colleagues
to you nor do I want to use your services to find me a job. I stop
reading unsolicited email as soon as I determine it is job-recruitment

-----------== Posted via Deja News, The Discussion Network ==----------

Ron Natalie

unread,
Feb 16, 1999, 3:00:00 AM2/16/99
to rods...@acm.org
Rod Spade wrote:
>
> Picky detail: I think in C "T foo();" is the same as "T foo(...);", not
> "T foo(void)" as in C++. (Of course, that's not relevant for the
> argument at hand.)

No T foo() in C means a function declared without specifying what
the arguments are. T foo(...) means a function declared as taking
a variable number of arguments. There is a difference.

There's a horrid bug related to that in G++ by the way.
It interprets:

extern "C" void foo()

as meaning a function with variable arguments and C linkage
rathern than a function taking no arguments with C linkage.
(that is, changing the linkdage should not change the behavior
of the rest of the declaration.

Seth Jones

unread,
Feb 16, 1999, 3:00:00 AM2/16/99
to
In article <7ab7hg$3go$1...@nnrp1.dejanews.com>,
alexande...@telrad.co.il says...

> Can we write int() to call the default ctor (so to speak) for ints ?

You mean the one that gives you whatever garbage happens to be on the
stack? I can't imagine why you would want to.

Seth Jones

Larry Brasfield

unread,
Feb 16, 1999, 3:00:00 AM2/16/99
to
Seth Jones wrote in message ...

The default ctor for built-in types is defined by the
language to zero-initialized the object. This is
especially useful in templates where the default
constructed value may be used as the default
for an optional argument. It is also useful to
explicitly name the default constructor in the
initialization list sometimes to ensure that a
member gets a repeatable value.

For example:

template < class T > class ValueWrapper {
T myValue;
public:
ValueWrapper() : myValue() {}
...
};

The default ctor for ValueWrapper<int> would
cause the myValue member to be initialized
to 0. This would be true whether the object
was allocated on the stack or not.

0 new messages