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

functions vs. static member functions

1 view
Skip to first unread message

Dobi

unread,
Aug 19, 2010, 3:03:15 PM8/19/10
to
Hello,

I'm trying to find out, if the following two codes are equivalent:

// 1
class foo {
public:
static int val;
static void bar() { val = 0; }
};

// 2
namespace foo {
int val;
void bar() { val = 0; }
}

It would be cool, if someone could help me.

Regards,
Dobi

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Daniel Krügler

unread,
Aug 19, 2010, 10:35:02 PM8/19/10
to
On 19 Aug., 21:03, Dobi <ha...@daiw.de> wrote:
> Hello,
>
> I'm trying to find out, if the following two codes are equivalent:

I hope this is no homework question.

> // 1
> class foo {
> public:
> static int val;
> static void bar() { val = 0; }
> };
>
> // 2
> namespace foo {
> int val;
> void bar() { val = 0; }
> }
>
> It would be cool, if someone could help me.

It depends on what you mean with "equivalent" ;-)
Surely both code snippets are very different from
the language point of view. It is common, that
in both (1) foo::val and foo::bar() and in
(2) foo::val and foo::bar() all have external
linkage and a C++ language linkage. Also, both
(1) foo::bar() and (2) foo::bar() are functions
that can be assigned to a function pointer
void (*)() and both (1) foo::val and (2) foo::val
have a static storage duration.

Among other things, there are some differences:

a) in (1) the definition of foo::val is lacking,
while in (2) foo::val is declared *and* defined.
To close this gap, you need to define in (1) as
follows:

int foo::val;

b) in (1) the function foo::bar is implicitly
inline, but in (2) foo::bar is no inline function.

HTH & Greetings from Bremen,

Daniel Krügler

Stuart Golodetz

unread,
Aug 19, 2010, 10:41:41 PM8/19/10
to
Dobi wrote:
> Hello,
>
> I'm trying to find out, if the following two codes are equivalent:
>
> // 1
> class foo {
> public:
> static int val;
> static void bar() { val = 0; }
> };
>
> // 2
> namespace foo {
> int val;
> void bar() { val = 0; }
> }
>
> It would be cool, if someone could help me.
>
> Regards,
> Dobi

Depends on your notion of equivalence, I guess, but for my vote no. For one thing:

// 1
class fooC {


public:
static int val;
static void bar() { val = 0; }
};

// 2
namespace fooN {


int val;
void bar() { val = 0; }
}

int main()
{
//fooC::val = 23; // would cause "unresolved external symbol"
fooN::val = 23; // fine
return 0;
}

Regards,
Stu

CornedBee

unread,
Aug 19, 2010, 10:41:41 PM8/19/10
to
On Aug 19, 12:03 pm, Dobi <ha...@daiw.de> wrote:
> Hello,
>
> I'm trying to find out, if the following two codes are equivalent:
>
> // 1
> class foo {
> public:
> static int val;
> static void bar() { val = 0; }
>
> };
>
> // 2
> namespace foo {
> int val;
> void bar() { val = 0; }
>
> }

No. On the surface, they are very similar, but there are lots of
subtle differences. ADL only applies to functions on namespace level,
for example, so bar#1 cannot be found that way. You can do using
foo::val or using namespace foo in the second example, but not in the
first (except in a derived class, which is special). In the first
case, though, you could use foo as a template parameter and have the
template access the static members; namespaces cannot be template
arguments. Also, the class foo can be derived from to get unqualified
access to its members. Finally, the namespace foo can be reopened,
whereas the class foo cannot.

As you can see, lots and lots of differences.

Mathias Gaunard

unread,
Aug 20, 2010, 5:01:42 PM8/20/10
to
On Aug 19, 8:03 pm, Dobi <ha...@daiw.de> wrote:
> Hello,
>
> I'm trying to find out, if the following two codes are equivalent:
>
> // 1
> class foo {
> public:
> static int val;
> static void bar() { val = 0; }
>
> };
>
> // 2
> namespace foo {
> int val;
> void bar() { val = 0; }
>
> }
>
> It would be cool, if someone could help me.

1) You can add stuff to a namespace, but not to a class.
2) namespaces have special lookup rules through ADL

Thiago A.

unread,
Aug 20, 2010, 5:18:28 PM8/20/10
to
{ It is advisable in this case that you reply directly to Dobi's post,
with only a single level of quoting, since you're apparently not
replying to anything that CornedBee wrote. Please include propler
attribution (such as "Foobar wrote:"). -mod }

> > I'm trying to find out, if the following two codes are equivalent:
>
> > // 1
> > class foo {
> > public:
> > static int val;
> > static void bar() { val = 0; }
>
> > };
>
> > // 2
> > namespace foo {
> > int val;
> > void bar() { val = 0; }
>
> > }

Depends on what you need.

Reasons to use static functions. (Function F member of type T)

* When F must me packed together with type T – like type traits

* When F needs to access private parts (data or typedefs) of T

If F already depends on public types or static values of T, I think is
reasonable to make F static member of T.

If F doesn't depend of T and F doesn't require to be packed in T them
is better non member function because you will decrease coupling.

If possible, is good to hide details like to make val visible only
inside a translation unit.

thorste...@gmx.de

unread,
Aug 21, 2010, 10:13:44 PM8/21/10
to
On Aug 19, 9:03 pm, Dobi <ha...@daiw.de> wrote:
> Hello,
>
> I'm trying to find out, if the following two codes are equivalent:
>
> // 1
> class foo {
> public:
> static int val;
> static void bar() { val = 0; }
>
> };
>
> // 2
> namespace foo {
> int val;
> void bar() { val = 0; }
>
> }
>
> It would be cool, if someone could help me.
>
> Regards,
> Dobi

maybe the most important difference:

from class foo you can create an object:
foo myFoo;

from the namespace that's not possible

Dobi

unread,
Aug 22, 2010, 4:13:29 PM8/22/10
to
On 20 Aug., 04:35, Daniel Krügler <daniel.krueg...@googlemail.com>
wrote:

> I hope this is no homework question.
No, this was not a homework question. I stumbled over this while
talking about static member functions to someone.

> b) in (1) the function foo::bar is implicitly
> inline, but in (2) foo::bar is no inline function.
Does the standard allow the compiler to inline static member functions
for optimization but does not allow it for regular functions, or why
is foo::bar in (1) is implicitly inline, but not in (2)?

Daniel Krügler

unread,
Aug 24, 2010, 2:08:16 AM8/24/10
to
On 22 Aug., 22:13, Dobi <ha...@daiw.de> wrote:
> On 20 Aug., 04:35, Daniel Krügler <daniel.krueg...@googlemail.com>

[..]

> b) in (1) the function foo::bar is implicitly
> > inline, but in (2) foo::bar is no inline function.
>
> Does the standard allow the compiler to inline static member functions
> for optimization but does not allow it for regular functions, or why
> is foo::bar in (1) is implicitly inline, but not in (2)?

The existing rule is just a convenience rule: If
the member function is defined within its class,
it's implicitly inline. This has nothing to do
what a compiler will actually do with any function.
It might ignore any inline specifier in the sense
that the code wont be "expanded" and it might
inline any non-inline function. Nevertheless the
inline keyword has a very special semantics
(e.g. related to the ODR and some further guarantees)
that a programmer and a compiler must honor.
E.g. if you as a programmer define a non-inline
function with external linkage within a header file
and that header file is part of more than one
translation unit of a program, this leads to
undefined behaviour.

HTH & Greetings from Bremen,

Daniel Krügler


0 new messages