Это может быть правдой, что:
полностью согласуется с обоими вышеперечисленными функциями и по-прежнему делает еще одну точку:
Другие ответы или, по крайней мере, некоторые из них либо делают точки 1 и 2, но не 3, либо делают точки 3 и нижние точки 1 и 2. Но все три являются истинными.
Возможно, что переключение лошадей в середине потока здесь потребует значительного поломки и что может возникнуть больше проблем, связанных с изменением Python, чтобы интуитивно обработать открывающий фрагмент Стефано. И это может быть правдой, что кто-то, кто хорошо знал внутренности Python, мог объяснить минные поля последствий. Однако
Существующее поведение не является Pythonic, а Python успешным, потому что очень мало о языке нарушает принцип наименьшего удивления где-нибудь возле , это плохо , Это настоящая проблема, было бы разумно ее искоренить. Это дефект дизайна. Если вы понимаете язык намного лучше, пытаясь проследить поведение, я могу сказать, что C ++ делает все это и многое другое; вы многому научитесь, перейдя, например, на тонкие ошибки указателя. Но это не Pythonic: людям, которые заботятся о Python достаточно, чтобы упорствовать перед лицом этого поведения, являются люди, которые тянутся к этому языку, потому что у Python гораздо меньше сюрпризов, чем на другом языке. Dabblers и любопытные становятся Pythonistas, когда они удивляются тому, как мало времени требуется, чтобы получить что-то работающее - не из-за дизайна fl - я имею в виду, скрытая логическая головоломка - которая урезает интуицию программистов, которые тянутся к Python потому что он просто работает.
Из C99 Standard (акцент мой)
6.5.3.4/2
Оператор sizeof дает размер (в байты) его операнда, который может быть выражением или заключенным в скобки именем типа. Размер определяется по типу операнда. Результат - целое число. Если тип операнда - тип массива переменной длины, то операнд оценивается; в противном случае операнд не оценивается, а результат является целочисленной константой.
Выполнение не может произойти во время компиляции. Поэтому ++i
/ i++
не будет. Также sizeof(foo())
не будет выполнять функцию, но вернет правильный тип.
sizeof
является выражением постоянной времени компиляции & quot ;?
– curiousguy
23 November 2011 в 10:18
Поскольку операнд оператора sizeof
не оценивается, вы можете сделать это:
int f(); //no definition, which means we cannot call it
int main(void) {
printf("%d", sizeof(f()) ); //no linker error
return 0;
}
Демо-версия онлайн: http://ideone.com/S8e2Y
То есть вам не нужно определять функцию f
, если она используется только в sizeof
. Этот метод в основном используется в метапрограммировании шаблонов C ++, так как даже в C ++ операнд sizeof
не оценивается.
Почему это работает? Он работает, потому что оператор sizeof
не работает с значением , вместо этого он работает с типом выражения. Поэтому, когда вы пишете sizeof(f())
, он работает с типом выражения f()
, и это не что иное, как возвращаемый тип функции f
. Тип возврата всегда один и тот же, независимо от того, какое значение возвратит функция, если оно действительно выполняется.
В C ++ вы можете даже это:
struct A
{
A(); //no definition, which means we cannot create instance!
int f(); //no definition, which means we cannot call it
};
int main() {
std::cout << sizeof(A().f())<< std::endl;
return 0;
}
Однако похоже, в sizeof
я сначала создаю экземпляр A
, записывая A()
, а затем вызывая функцию f
в экземпляре, написав A().f()
, но такого не происходит.
Демо: http://ideone.com/egPMi
Вот еще одна тема, которая объясняет некоторые другие интересные свойства sizeof
:
sizeof
является встроенным оператором компиляции и не является функцией. Это становится очень ясным в тех случаях, когда вы можете использовать его без скобок:
(sizeof x) //this also works
sizeof(foo)
действительно пытается обнаружить размер выражения во время компиляции:
6.5.3.4:
Оператор sizeof дает размер (в байтах) ) его операнда, который может быть выражением или заключенным в скобки именем типа. Размер определяется по типу операнда. Результат - целое число. Если тип операнда - тип массива переменной длины, то операнд оценивается; в противном случае операнд не оценивается, а результат является целочисленной константой.
Короче: массивы переменной длины, выполняемые во время выполнения. (Примечание: Массивы переменной длины - это определенная функция - не массивы, выделенные с помощью
malloc(3)
.) В противном случае вычисляется только тип выражения и что при компиляции время.
sizeof()
дает размер только типа данных, он не оценивает внутренние элементы.
sizeof
фактически является макросом - он не создает код, а предварительно вычисляет ожидаемое значение и вносит его прямо в код. Обратите внимание, что это было поведение only i> до C99, поскольку VBAs не существовало (я бы никогда не слышал о них до этого ответа, верьте или нет!)
– Corley Brigman
24 February 2014 в 20:17
sizeof (char[x++]);
использует значение x
для чего-либо иного, кроме определения значения выражения x++
и нового значения для x
, оба из которых являются нормальными с этим оператором?
– supercat
24 February 2014 в 21:21
char[x++]
- VLA. он выглядит эффектно, как char*
для моих незнакомых глаз.
– Corley Brigman
25 February 2014 в 20:30
N
из stdin и makeint array[N]
. Это одна из функций C99, недоступная в C ++. – Kos 22 November 2011 в 13:23sizeof(int[++x])
(действительно, действительно плохая идея, во всяком случае) можно оценить++
. – Jens Gustedt 22 November 2011 в 14:01