â ď¸ Namespace are implemented up-stream, but the playground does not support it yet
Big code projects must support namespaces to organize large codebases. So SuperC will not survive without namespacing.
Namespaces are not intended to reduce the amount of typing, but to organize the code and prevent name collisions.
But in order to keep it simple and avoid ânamespace hellâ:
:: is treated as part of the identifier name.foo::bar is foo$$bar.using namespace foo; only explicit usage like foo::bar.SuperC allows the use of :: inside identifier names (but not single character :, as that would conflict with label parsing)
foo, foo::bar, foo::bar::baz, etc.foo:::bar, foo:bar, etc.Instead of constantly typing foo:: before all the identifiers in your header files, you can use #pragma namespace foo, this assigns the name prefix to foo::.
#pragma namespace foo to tell the compiler to prepend foo:: to all eligible identifiers names.#pragma namespace to end the current namespace. i.e., set name prefix to empty.#include directive, the name prefix is restored to the previous one, preventing the included file from hoisting the name prefix.Same as name prefix, there is also a symbol prefix (see #pragma namespace_symbol)
#pragma namespace is reached, the symbol prefix is reset. i.e., #pragma namespace foo makes the symbol prefix foo$$ and the name prefix foo::.Note: the
#pragma namespacedirective replaces the previous one. If you invoke#pragma namespace fooand then#pragma namespace bar, the namespace is notfoo::bar, itâsbar. Use#pragma namespace foo::barto indicate a nested namespace.
#pragma namespace_symbol "foo_" to assign the symbol prefix to âfoo_â instead of the default foo$$.#pragma namespace_symbol "" effectively disables the symbol prefix, useful for wrappers.#include directive, the symbol prefix is restored to the previous one, preventing the included file from hoisting the symbol prefix.#pragma namespace directive is reached, the symbol prefix is reset to default. See #pragma namespaceYou can use a macro to reduce deep nested namespaces in some cases.
#define Arithmetic Math::Algebra::Arithmetic
printf("%d\n", Arithmetic::Add(1, 2)); // equivalent to Math::Algebra::Arithmetic::Add
#include <stdio.h>
// no namespace
int sum(int a, int b) {
return a + b;
}
// explicit namespace
int mylib::sum(int a, int b) {
return a + b + 1;
}
/* -- BEGIN NAMESPACE: mylib -- */
#pragma namespace mylib
const int TWO = 2; // symbol : mylib$$TWO
int add(int a, int b) { // symbol : mylib$$add
return a + b + mylib::TWO;
}
// methods don't get namespace, so this is
// not '(int).mylib::sum', but just '(int).sum'
int (int a) sum(int b) {
return a + b;
}
#pragma namespace // end namespace
int main() {
int x = 3;
printf("A: %d\n", sum(1, 2));
printf("B: %d\n", mylib::sum(1, 2));
printf("C: %d\n", mylib::add(1, 2));
printf("D: %d\n", x.sum(4)); // (int).sum
// A: 3
// B: 4
// C: 6
// D: 7
return 0;
}
#include <stdarg.h>
#pragma namespace std
#pragma namespace_symbol "" // disable symbol mangling
// wrap all std headers inside `std::`
#include <stdio.h>
#include <stdlib.h>
#pragma namespace // end namespace
// warning: 'std::printf' has symbol "printf",
// so change the symbol of this function to avoid collision
void printf(const char *format, ...) __attribute__((symbol("myprintf"))) {
va_list args;
va_start(args, format);
std::puts("Hi: ");
std::vprintf(format, args);
va_end(args);
}
int main() {
printf("Hello world\n"); // output: "Hi: Hello world\n"
std::printf("OK\n"); // the classic printf from <stdio.h>
return 0;
}
#include <stdio.h>
#include "sdl_wrapper.h"
int main() {
/* Init SDL */
if (SDL::Init(SDL_INIT_VIDEO) != 0)
return 1;
defer SDL::Quit();
/* Create window */
SDL::Window *game_window = SDL::CreateWindow("Defer test",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
640, 480, SDL_WINDOW_SHOWN);
if (!game_window)
return 2;
defer SDL::DestroyWindow(game_window);
...
printf("OK\n");
return 0;
}
#include <SDL2/SDL.h>
#pragma namespace SDL
#pragma namespace_symbol "SDL_"
// SDL::Init -> SDL_Init
// SDL::Quit -> SDL_Quit
// ...
typedef SDL_Window Window;
typedef SDL_Renderer Renderer;
extern DECLSPEC int SDLCALL Init(Uint32 flags);
extern DECLSPEC void SDLCALL Quit(void);
extern DECLSPEC SDL::Window * SDLCALL CreateWindow(const char *title,
int x, int y, int w,
int h, Uint32 flags);
extern DECLSPEC void SDLCALL DestroyWindow(SDL::Window * window);
// namespace will automatically end at the end of the file