Dlaczego sizeof jest uważany za operatora?

95

Dlaczego jest sizeofuważany za operator, a nie funkcję?

Jaka właściwość jest konieczna, aby zostać operatorem?

Arpit
źródło

Odpowiedzi:

183

Ponieważ norma C tak mówi i otrzymuje jedyny głos.

Jako konsekwencje:

  • Operand sizeof może być typem ujętym w nawias sizeof (int)zamiast wyrażeniem obiektowym.
  • Nawiasy są niepotrzebne: wszystko w int a; printf("%d\n", sizeof a);porządku. Są często widoczne, po pierwsze dlatego, że są potrzebne jako część wyrażenia rzutowania typu, a po drugie, ponieważ sizeof ma bardzo wysoki priorytet, więc sizeof a + bnie jest tym samym, co sizeof (a+b). Ale nie są częścią wywołania sizeof, są częścią operandu.
  • Nie możesz wziąć adresu o rozmiarze sizeof.
  • Wyrażenie, które jest operandem parametru sizeof, nie jest obliczane w czasie wykonywania ( sizeof a++nie modyfikuje a).
  • Wyrażenie, które jest operandem parametru sizeof, może mieć dowolny typ z wyjątkiem void lub typów funkcji. Rzeczywiście, w pewnym sensie chodzi o sizeof.

Funkcja różniłaby się we wszystkich tych punktach. Prawdopodobnie istnieją inne różnice między funkcją a operatorem jednoargumentowym, ale myślę, że to wystarczy, aby pokazać, dlaczego sizeof nie może być funkcją, nawet jeśli istniał powód, aby tak było.

Steve Jessop
źródło
3
Wow, właśnie o tym myślałem!
crashmstr
7
Nie mogę tego lepiej powiedzieć.
Clement Herreman
Uważam, że obecnie sprawy są bardziej złożone ze względu na tablice o zmiennej długości (VLA). IIRC, standard pozwoliłby nawet sizeofna efekty uboczne, jeśli w wyrażeniu jest VLA.
Aaron McDaid
@glglgl Nie, to nie ma sensu. W tym kontekście (int)nie ma nic wyszukanego - tylko nazwa typu w nawiasach. Nawiasy są tutaj częścią składni sizeof- są wymagane przy określaniu rozmiaru typu, ale nie są wymagane przy określaniu rozmiaru wyrażenia. Zobacz np. Tutaj
anatolyg
1
Standard używa dwóch notacji dla sizeof: sizeof unary-expressioni sizeof ( type-name )- tak więc w standardzie C11 nie jest uważany za „rzutowanie”, ale nazwę typu w nawiasach. Wynik netto jest bardzo podobny. (Dla porównania, wyrażenie to ( type-name ) cast-expression.) I nienawidzę tego, że komentarz Markdown działa inaczej niż Q&A Markdown!
Jonathan Leffler
24

Może być używany jako stała czasu kompilacji, co jest możliwe tylko wtedy, gdy jest operatorem, a nie funkcją. Na przykład:

union foo {
    int i;
    char c[sizeof(int)];
};

Składniowo, gdyby nie był to operator, musiałoby to być makro preprocesora, ponieważ funkcje nie mogą przyjmować typów jako argumentów. Byłoby to trudne do zaimplementowania makro, ponieważ sizeofmoże przyjmować zarówno typy, jak i zmienne jako argument.

John Kugelman
źródło
4
+1, ale zauważ, że nie jest to stała czasu kompilacji, gdy argumentem jest tablica VLA o zmiennej długości.
Jonathan Leffler
6

Ponieważ norma C tak mówi i otrzymuje jedyny głos.

A standard jest prawdopodobnie poprawny, ponieważ sizeofprzyjmuje typ i

Ogólnie rzecz biorąc, jeśli domena lub kodomena (lub obie) funkcji zawiera elementy znacznie bardziej złożone niż liczby rzeczywiste, funkcja ta jest określana jako operator. I odwrotnie, jeśli ani domena, ani kodomena funkcji nie zawierają elementów bardziej skomplikowanych niż liczby rzeczywiste, funkcja ta będzie prawdopodobnie nazywana po prostu funkcją. Funkcje trygonometryczne, takie jak cosinus, są przykładami tego ostatniego przypadku.

Dodatkowo, gdy funkcje są używane tak często, że ewoluowały szybciej lub łatwiej niż ogólna forma F (x, y, z, ...), wynikające z nich formy specjalne są również nazywane operatorami. Przykłady obejmują operatory wrostkowe, takie jak dodawanie „+” i dzielenie „/”, oraz operatory przyrostków, takie jak silnia „!”. To użycie nie ma związku ze złożonością zaangażowanych podmiotów.

(Wikipedia)

Daniel Brückner
źródło
To prawdopodobnie wyjaśnia motywację standardu C (i innych języków programowania) do używania terminów „operator” i „funkcja”, tak jak to robią.
Steve Jessop
5

Ponieważ to nie jest funkcja. Możesz go używać w ten sposób:

int a;
printf("%d\n", sizeof a);

Funkcja ma punkt wejścia, kod itp. Funkcja ma być uruchamiana w czasie wykonywania (lub wbudowana), sizeof musi być określone w czasie kompilacji.

Michał Górny
źródło
2

Operator sizeof jest jednostką czasu kompilacji, a nie uruchomieniem i nie potrzebuje nawiasów jak funkcja. Kiedy kod jest kompilowany, zastępuje wartość rozmiarem tej zmiennej w czasie kompilacji, ale w funkcji po wykonaniu funkcji będziemy znać zwracaną wartość.

Deepak Kumar 'SORTED'
źródło
1

Dlatego:

  • kiedy przekazujesz wartość do funkcji, rozmiar obiektu nie jest przekazywany do funkcji, więc sizeof„funkcja” nie miałaby możliwości określenia rozmiaru
  • w C funkcje mogą przyjmować tylko jeden typ argumentu; sizeof () musi akceptować różne różne rzeczy (zarówno zmienne, jak i typy! Nie możesz przekazać typu do funkcji w C)
  • wywołanie funkcji wiąże się z utworzeniem kopii argumentów i innymi niepotrzebnymi narzutami
Artelius
źródło
1

Jest mała różnica w stosunku do funkcji - wartość sizeof jest rozwiązywana w czasie kompilacji, ale nie w czasie wykonywania!

Dewfy
źródło
7
Z wyjątkiem VLA - tablica o zmiennej długości - argumenty.
Jonathan Leffler
1

Ponieważ jest to operator czasu kompilacji, który w celu obliczenia rozmiaru obiektu wymaga informacji o typie, które są dostępne tylko w czasie kompilacji. To nie dotyczy C ++.

João Silva
źródło
0

sizeof()operator jest czasem kompilacji. Może służyć do określenia parametrów lub argumentów.

ganesh
źródło
-1

Sizeof (), myślę, że oczywiście jest to zarówno funkcja, jak i operator. Czemu? Ponieważ funkcja zawiera nawiasy do wpisywania na etapie wprowadzania. Ale głównie operatory powodują, że operatory są znakami akcji, dlatego sizeof jest instrukcją akcji, która działa na operandzie w nawiasach.

Enoch Asanda Hall
źródło