Dlaczego ANSI C nie ma przestrzeni nazw?
Posiadanie przestrzeni nazw wydaje się nie zastanawiać dla większości języków. Ale z tego co wiem, ANSI C go nie wspiera. Dlaczego nie? Jakieś plany włączenia go do przyszłego standardu?
9 answers
C ma przestrzenie nazw. Jeden dla znaczników struktury, a drugi dla innych typów. Rozważmy następującą definicję:
struct foo
{
int a;
};
typedef struct bar
{
int a;
} foo;
Pierwszy z nich ma tag foo, a późniejszy jest przekształcony w typ foo z typedef. Nadal nie dochodzi do starć z nazwiskami. Dzieje się tak, ponieważ znaczniki i typy struktury (typy wbudowane i typy typedef ' ed) żyją w oddzielnych przestrzeniach nazw.
C nie pozwala na tworzenie nowej przestrzeni nazw za pomocą woli. C został znormalizowany, zanim uznano to za ważne w język i dodawanie przestrzeni nazw zagroziłoby również kompatybilności wstecznej, ponieważ wymaga to manipulowania nazwami, aby działać poprawnie. Myślę, że można to przypisać ze względu na aspekty techniczne, a nie filozofię.
Edytuj: JeremyP na szczęście poprawił mnie i wspomniał o przestrzeniach nazw, które przegapiłem. Istnieją przestrzenie nazw dla etykiet oraz dla członków struct/union.
Dla kompletności istnieje kilka sposobów osiągnięcia "korzyści", które możesz uzyskać z przestrzeni nazw, w C.
Jedną z moich ulubionych metod jest użycie struktury do przechowywania kilku wskaźników metod, które są interfejsem do twojej Biblioteki/etc..
Następnie używasz zewnętrznej instancji tej struktury, którą inicjalizujesz wewnątrz biblioteki, wskazując na wszystkie twoje funkcje. Pozwala to zachować proste nazwy w bibliotece bez wchodzenia w Przestrzeń nazw klientów (inną niż zmienna extern w zasięgu globalnym, 1 zmienna vs prawdopodobnie setki metod..)
W grę wchodzi dodatkowa konserwacja, ale uważam, że jest ona minimalna.
Oto przykład:
/* interface.h */
struct library {
const int some_value;
void (*method1)(void);
void (*method2)(int);
/* ... */
};
extern const struct library Library;
/* interface.h */
/* interface.c */
#include "interface.h"
void method1(void)
{
...
}
void method2(int arg)
{
...
}
const struct library Library = {
.method1 = method1,
.method2 = method2,
.some_value = 36
};
/* end interface.c */
/* client code */
#include "interface.h"
int main(void)
{
Library.method1();
Library.method2(5);
printf("%d\n", Library.some_value);
return 0;
}
/* end */
Użycie . składnia tworzy silne skojarzenie z klasyczną metodą Library_function () Library_some_value. Istnieją jednak pewne ograniczenia, z których nie można używać makr jako funkcji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-20 13:33:46
C ma przestrzenie nazw. Składnia to namespace_name
. Można je nawet zagnieżdżać jak w general_specific_name
. A jeśli chcesz mieć dostęp do nazw bez każdorazowego wypisywania nazwy przestrzeni nazw, Dołącz odpowiednie makra preprocesora do pliku nagłówkowego, np.
#define myfunction mylib_myfunction
Jest to o wiele czystsze niż manipulowanie nazwami i inne okrucieństwa, które niektóre języki zobowiązują się do dostarczania przestrzeni nazw.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 14:18:27
Historycznie kompilatory C nie mangle nazw (robią to w Windows, ale mangling dla cdecl
konwencji wywołania polega tylko na dodaniu prefiksu podkreślenia).
Ułatwia to Korzystanie z bibliotek C z innych języków (w tym asemblera) i jest jednym z powodów, dla których często widzisz extern "C"
wrappery dla interfejsów API C++.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 10:44:57
Tylko z powodów historycznych. nikt wtedy nie myślał o posiadaniu czegoś takiego jak przestrzeń nazw. Również oni naprawdę starali się utrzymać język prosty. Mogą mieć go w przyszłości
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 08:28:46
Nie odpowiedź, ale nie komentarz. C nie dostarcza sposobu na jawne zdefiniowanie namespace
. Ma zmienny zasięg. Na przykład:
int i=10;
struct ex {
int i;
}
void foo() {
int i=0;
}
void bar() {
int i=5;
foo();
printf("my i=%d\n", i);
}
void foobar() {
foo();
bar();
printf("my i=%d\n", i);
}
Możesz używać kwalifikowanych nazw zmiennych i Funkcji:
mylib.h
void mylib_init();
void mylib_sayhello();
Jedyną różnicą od przestrzeni nazw jest to, że nie można być using
i nie można importować from mylib
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 08:41:05
ANSI C zostało wynalezione przed przestrzeniami nazw.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 08:30:23
Ponieważ ludzie, którzy chcą dodać tę możliwość do C, nie zebrali się i nie zorganizowali, aby wywierać presję na zespoły autorów kompilatorów i na organy ISO.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-01 11:44:41
C nie obsługuje przestrzeni nazw takich jak C++. Implementacja przestrzeni nazw w języku C++ powoduje zmianę nazw. Podejście opisane poniżej pozwala uzyskać korzyści z przestrzeni nazw w C++, mając nazwy, które nie są zniekształcone. Zdaję sobie sprawę, że naturą pytania jest to, dlaczego C nie obsługuje przestrzeni nazw (a trywialną odpowiedzią byłoby to, że nie, ponieważ nie został zaimplementowany :)). Pomyślałem tylko, że może komuś pomóc zobaczyć jak zaimplementowałem funkcjonalność szablonów i przestrzenie nazw.
Napisałem tutorial jak wykorzystać przestrzenie nazw i / lub szablony używając C.
Przestrzenie nazw i szablony w C
Przestrzenie nazw i szablony w C (używając list linkowanych)
Dla podstawowej przestrzeni nazw, można po prostu przedrostek nazwy przestrzeni nazw jako konwencję.
namespace MY_OBJECT {
struct HANDLE;
HANDLE *init();
void destroy(HANDLE * & h);
void do_something(HANDLE *h, ... );
}
Można zapisać jako
struct MY_OBJECT_HANDLE;
struct MY_OBJECT_HANDLE *my_object_init();
void my_object_destroy( MY_OBJECT_HANDLE * & h );
void my_object_do_something(MY_OBJECT_HANDLE *h, ... );
Drugim podejściem, którego potrzebowałem, wykorzystującym koncepcję przestrzeni nazw i szablonów, jest użycie makra konkatenacja i include. Na przykład, mogę utworzyć
template<T> T multiply<T>( T x, T y ) { return x*y }
Używanie plików szablonów w następujący sposób
Multiply-template.h
_multiply_type_ _multiply_(multiply)( _multiply_type_ x, _multiply_type_ y);
Multiply-template.c
_multiply_type_ _multiply_(multiply)( _multiply_type_ x, _multiply_type_ y) {
return x*y;
}
Możemy teraz zdefiniować int_multiply w następujący sposób. W tym przykładzie utworzę int_multiply.h/.plik C.
Int_multiply.h
#ifndef _INT_MULTIPLY_H
#define _INT_MULTIPLY_H
#ifdef _multiply_
#undef _multiply_
#endif
#define _multiply_(NAME) int ## _ ## NAME
#ifdef _multiply_type_
#undef _multiply_type_
#endif
#define _multiply_type_ int
#include "multiply-template.h"
#endif
Int_multiply.c
#include "int_multiply.h"
#include "multiply-template.c"
Na końcu tego wszystkiego, będziesz miał funkcję i plik nagłówka dla.
int int_multiply( int x, int y ) { return x * y }
Stworzyłem znacznie bardziej szczegółowy samouczek na temat podanych linków, które pokazują, jak to działa z połączonymi listami. Mam nadzieję, że to komuś pomoże!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-29 23:20:56