I define a lot of classes in my cpp files. Often with unimaginative names, such as 'Implementation'. and am worried about name collisions, as these are horrible to debug (assuming the compiler silently drops one of the definitions). However, I also want to be able to debug my program, so anonymous namespaces are not an option. So, can file-scoped (aka. translation-unit scoped) classes be defined in c++ without using namespaces? If yes, how?
File-scoping in c
In c, one can create a global variable with int foo;, and limit the variable to file-scope using static int foo;. Similarly, file-scoped functions are also created with the static keyword, for example static void bar();. And structs do not define data or executable code, and thus are effectively always file-scoped.
Virtual member functions
Now c++ introduced virtual member functions, which caused structs (aka. classes) to contain data and executable code. Hence structs are now globally defined. However, it is not allowed to use static to make the struct file-scoped again. I.e. static struct Foo{}; does not compile.
Namespaces
To tackle the problem of name collisions, c++ also introduced named namespaces. Those can also be used to wrap the struct, such that it becomes pseudo-file-scoped. Though this still forces you to pick a unique name (that you don't even care about) for every file. As a solution, they also introduced anonymous namespaces. Unfortunately, neither gdb nor the visual studio debugger seem to support anonymous namespaces (it is basically impossible to refer to anything inside the anonymous namespace).
A partial solution is to use anonymous structs/classes and typedef these, as both are file-scoped (C - Limit struct Scope), except that it is impossible to explicitly define constructors or destructors (Constructor for a no-named struct). The following example compiles and runs fine with gcc and also allows gdb to put a breakpoint on method():
interface.h:
struct Iface {
virtual void method()=0;
};
implementation_a.cpp and implementation_b.cpp:
#include "interface.h"
typedef struct : Interface {
virtual void method();
} Implementation;
void Implementation::method() {
// Do stuff...
}
Interface * new_implementation_a() { // or new_implementation_b
return new Implementation();
}
main.cpp:
#include "iface.h"
int main() {
Interface * a = new_implementation_a();
Interface * b = new_implementation_b();
a->method();
b->method();
return 0;
}
Related
I read in the below link that unnamed(anonymous) class should not have static data memebers in it. Could anyone please let me know the reason for it?
https://www-01.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.cbclx01/cplr038.htm
says the below..
You can only have one definition of a static member in a program.
Unnamed classes, classes contained within unnamed classes, and local
classes cannot have static data members.
All static member data, if they are ODR-used, must be defined outside the class/struct.
struct Foo
{
static int d;
};
int Foo::d = 0;
If the class/struct is unnamed, there is no way to define the member outside the class.
int ::d = 0;
cannot be used to define the static member of an unnamed class.
Update for C++17
If you are able to use C++17 or newer, you may use
static inline int d = 10;
That will allow a static member variable to be defined in an anonymous class/struct.
Sample code to demonstrate that a static member variable need not be defined outside the class definition:
#include <iostream>
struct foo
{
static inline int d = 10;
};
int main()
{
auto ptr = &foo::d;
std::cout << *ptr << std::endl;
}
Command to build:
g++ -std=c++17 -Wall socc.cc -o socc
Output of running the program:
10
Thanks are due to #Jean-MichaƫlCelerier for the suggestion for the update.
Are you sure that the standard actually forbids this?
As mentioned the problem arises as you need to have an actual definition of the static member. The language provides for no method to define it. There is no other problems in referring to it as we can do it from within the struct or via an instance of it.
However GCC for example will accept the following:
static struct {
static int j;
} a;
int main() {
return a.j; // Here we actually refers to the static variable
}
but it can't be linked as a.j refers to an undefined symbol (._0::j), but there's a way to get around this. By defining it in assembler or by using compiler extensions you could. For example adding the line
int j asm("_ZN3._01jE") = 42;
Will make it work. _ZN3._01jE is the real mangled name of the static variable in this case, neither the mangled or unmangled name can be used directly as a identifier in standard C++ (but it can via GCC extension or assembler).
As you must probably realize this would only work with specific compilers. Other compilers would mangle the name in other ways (or even do other things that may make the trick not work at all).
You should really question why you would like to use this trick. If you can do the work using standard methods you should most probably chose that. For example you could reduce the visibility by using anonymous namespace instead for example:
namespace {
static struct Fubar {
static int j;
} a;
Fubar::a = 0;
}
Now Fubar is not really anonymous, but it will at least be confined to the translation unit.
When C++ was standardized, unnamed classes could not have static data members, as there was no way to define/instantiate them. However, this problem has been solved with C++11, as it added the decltype operator:
struct {
static int j;
} a;
// Declare the static member of the unnamed struct:
int decltype(a)::j = 42;
int main() {
return a.j == 42 ? 0 : 1; // Use the static member
}
So, in principle, there could be unnamed classes or structs with static data members. But the C++ standard makers deliberately did not allow this syntax, as the compiler doesn't know, which name it should give to that decltype(a)::j thing for linking. So most (all?) compilers - including current versions of GCC in normal mode - refuse to compile this.
In -fpermissive mode, GCC-9 und GCC-10 accept this code and compile it fine. However, if the declaration of a is moved to a header file, that is included from different source files, they still fail at the linking stage.
So unnamed classes can only be used inside a single translation unit. To avoid polluting the global namespace, just put anything, that needs to stay local, inside an anonymous namespace. So:
namespace {
struct whatever {
static int j;
} a;
int whatever::j = 42;
}
int main() {
return a.j == 42 ? 0 : 1;
}
compiles fine, doesn't pollute global namespace, and even doesn't lead to problems, if the name whatever clashes with a name from another header file.
I came across the following code in an article
struct entire_program
{
struct B;
struct A
{
B *bbb;
void Aa() { B bb; bb.Bb(); };
};
struct B
{
A aaa;
void Bb() { A aa; aa.Aa(); };
};
};
Why am I allowed to call method Bb() in this case, but if I change struct entire_program to namespace entire_program it generates a compiler error?
I already read this question, what I am asking is: if it is possible to call methods that are undefined yet within classes/structs/unions why don't namespaces work the same way? I am interested in the motivation behind this behavior.
Related question on Programmers.SE (for those interested in the coding style presented in the article)
This is just the way classes and namespaces work in C++. Classes have to bring the entire set of (class member) names as candidates because otherwise you'd have a huge burden of ordering your class members and might not conveniently be able to order your public interface first, for example.
Namespaces on the other hand work almost exactly like C functions and are processed sequentially in the order they're listed in the source file. Special features aren't needed since you can always declare your function before calling it at namespace/global scope.
Circular dependency is possible inside both classes and namespaces. It is just a matter of defining things correctly in circular dependency situations.
In your case the code compiled with struct entire_program because of special treatment in-class member function definitions: they are allowed to "see" the entire definition of the enclosing class(es), both above and below the current point. But they cannot see the entire definition of the enclosing namespace. With namespaces the compiler only sees what has been declared above the current point.
Classes and namespaces are very different things, so the problem of switching freely between the two does not usually arise in practice. But just for illustrative purposes this can be achieved in many cases, including your artificial example
namespace entire_program
{
struct B;
struct A
{
B *bbb;
void Aa();
};
struct B
{
A aaa;
void Bb() { A aa; aa.Aa(); }
};
}
inline void entire_program::A::Aa()
{
B bb; bb.Bb();
}
My implementation above has the same effect as yours, but it does not rely on that special treatment of member functions. You can freely switch between struct entire_program and namespace entire_program, if you so desire. Just remember that namespace definition does not have a ; after the closing }.
I am currently implementing some utility functions for implementing some libraries I am working on. I was forced to choose between segmenting the functions as static members as part of a class definition within a more general namespace, or enter more specific namespace and then define the functions. I choose the former feeling as it was more flexible in the way those utility classes may be drawn into scope (using or inheritance) though I was unsure whether there was any overhead associated with this design choice or not:
Is
namespace Utilities {
struct CharUtil {
static void foo();
}
}
Utilities::CharUtil::foo();
slower than
namespace Utilities {
namespace CharUtil {
void foo();
}
}
Utilities::CharUtil::foo();
?
Is the former faster using inheritance?
There is no difference at all between the two cases, except for functions' mangled names. Static functions do not have this pointer as hidden argument. The compiler generated code for both functions will be the same.
Even though there are no static classes in C++, coming from a Java background I use to create a helper class like Util containing only static methods. Is this considered bad style or usual practice? One alternative I see is to use C functions (no class context at all). What other alternatives are there? What are there advantages and disadvantages and under which circumstances would I use any of these.
defining bunch of static methods in c++ suggests namespacing static functions as one alternative, though I fail to see what effects the static keyword without class context has.
If you want to create a collection of utility functions without clobbering the global namespace, you should just create regular functions in their own namespace:
namespace utility {
int helper1();
void helper2();
};
You probably don't want to make them static functions either.
Within the context of a non-member function (as opposed to a member function), the static keyword in C and C++ simply limits the scope of the function to the current source file (that is, it sort of makes the function private to the current file). It's usually only used to implement internal helper functions used by library code written in C, so that the resulting helper functions don't have symbols that are exposed to other programs. This is important for preventing clashes between names, since C doesn't have namespaces.
In C++, classes with only static methods is mostly used in template metaprogramming.
For example, I want to calculate fibonacci numbers at compile-time itself, and at runtime I want them to print only, then I can write this program:
#include <iostream>
template<int N>
struct Fibonacci
{
static const int value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
static void print()
{
Fibonacci<N-1>::print();
std::cout << value << std::endl;
}
};
template<>
struct Fibonacci<0>
{
static const int value = 0;
static void print()
{
std::cout << value << std::endl;
}
};
template<>
struct Fibonacci<1>
{
static const int value = 1;
static void print()
{
Fibonacci<0>::print();
std::cout << value << std::endl;
}
};
int main() {
Fibonacci<20>::print(); //print first 20 finonacci numbers
return 0;
}
Online demo : http://www.ideone.com/oH79u
C++ is a multi paradigm language, so if you need some util functions that perhaps don't really fit in a class at all, then I would just make them free functions. I don't see a reason to put them into a class, just for OOP's sake.
There is no advantage that I can see to making all functions static and putting them in a class, over having them just as free functions. Personally, I think free functions are then an easier to work with option.
As many others have pointed out, free functions inside a namespace is an approach that's often taken for this sort of thing in c++.
One case I'd make for classes with all static functions is when you'd like to expose a set of functions to information derived from template parameters, i.e.
template <typename Ty>
class utils
{
public :
// if you need to setup a bunch of secondary types, based on "Ty" that will be used
// by your utility functions
struct item_type
{
Ty data;
// etc
};
// a set of utilities
static void foo(Ty &data1, item_type &item)
{
// etc
}
};
You can use this to achieve the effect of a template'd namespace:
int main ()
{
double data;
utils<double>::item_type item ;
utils<double>::foo(data, item);
return 0;
}
If you're not using templates just stick with namespaces.
Hope this helps.
There is no real issue with declaring static methods within a class. Although namespaces are more suitable for this purpose for the reasons mentioned in the post you are referring to.
Using C functions can generate name collisions, unless you decide on a naming convention, prefixing your functions with stuff, for example btFunctionA, btFunctionB etc.
You will want to keep your symbols within namespaces to avoid that, you are using C++ and not C after all.
Static functions within a namespace aren't any different from non-static. I believe the static keyword is simply ignored in this context.
In C++, just make them free functions. There's no need or reason to place them in a class at all. Unless you're doing shizzle with templates.
This may be relevant to your interests. It is an article that, uh, examines the different approaches to classes and functions in Java compared to other languages.
http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
There is one other situation in which a static class might be preferred to a namespace: when you want to make the data private so that it can't be directly modified from outside the class/namespace, but for performance reasons you want to have have public inline functions that operate on it. I don't think there is any way to do that with a namespace, other than by declaring a class inside the namespace.
I have a few questions about the static keyword in C++ (and probably with other languages as well.) What is the purpose of declaring a function as static?
void static foo(int aNumber) {
... }
How about a static inline function?
void static inline foo(int aNumber) {
... }
Is there any benefit to using the static keyword with a function, and do those benefits apply to class functions as well?
I realize some datatypes like structs and arrays have to be static when compiling with an older compiler, but is there any point when using a new ANSI-C++ compiler (like MS VC++ 2008)? I know that using a static variable inside a loop saves time by keeping the data in memory and not reallocating memory every loop iteration, but how about when a variable is declared only once, like at the top of a header file or within a namespace?
Depends on Context:
Like many things in C++, static means different things depending on its context.
It's very common in C++ for the same word to mean different things depending on its context.
For example:
* is used for multiplication, dereferencing a pointer, and creating pointers.
& is used to get the address of variables, to declare a reference, and as a bitwise AND operator.
Global use of static:
If you declare a function or variable as static outside of a class and in global scope, it is specific to only that file. If you try to use that variable or function in a different file (via a forward declaration) you will get a linking error.
Example:
a.cpp:
static void fn()
{
cout<<"hello a!"<<endl;
}
b.cpp:
void fn();
void gn()
{
fn();//causes linking error
}
This feature allows you to use a function that no other file will ever see, that way you don't cause possible linker errors of a symbol defined multiple times. The preferred method to do this is with anonymous namespaces though:
a.cpp:
namespace
{
void fn() // will be static to a.cpp
{
cout<<"hello a!"<<endl;
}
}
Inside of a class use of static:
If you declare a function or variable as static inside of a class (or struct), it is a class function or class variable. This means that there is only one for that whole class. A class function can only use class variables. A class variable is shared amongst all instances of that class.
class C
{
public:
static void fn()
{
y = 4;//<--- compiling error
// can't access member variable within a static function.
}
int y;
}
This is a great feature to use if you have something that is specific to the class of your objects, but not specific to an instance.
Inside a function use of static:
If you declare a variable as static inside of a function, you can consider that the variable value will persist upon calls. It will only be initialized once.
Example:
//Will print 0, then 1, then 2, ...
void persistentPrintX()
{
static int x = 0;
cout << x << endl;
x++;
}
I personally try to avoid this, and you probably should to. It is not good to have global state. It is better to have functions that given the same input guarantees the same output.
Just like in the English language:
The concept of context sensitive meaning is not specific to C++, you can even see it in the English language.
I am going to screen a movie (Means showing the movie)
The screen on the TV is broken (Means a part of the TV)
Other meanings in other programming languages:
Depending on the programming language there can be a different meaning, but the first thing most people think of when you say static is a class variable/function vs a member variable/function.
I hang around on the ##c++ irc channel on irc.freenode.net and I really like the clarification on static that the bot nolyc is programmed to give. I quote word for word:
When used inside a function, the
static keyword indicates that a
variable is shared between all calls
of the function. When used inside a
class, it indicates that the variable
or function is a member but is not
tied to a specific instance. When
used inside a namespace, it specifies
internal linkage.
I hope that clears things up. I haven't answered all your questions. I would say that you should use the static keyword to do what it was intended to do. Use it as a tool to accompolish your task, if it is the right one for the job. As far as benefits go, I wouldn't worry. If you need to optimize, then think about those effects if there is no other resort.
I hope this helps.