Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.61
thick_int
Заблокирован
#1

Нюансы использования оператора sizeof() - C++

21.11.2011, 11:53. Просмотров 2923. Ответов 39
Метки нет (Все метки)

Пусть T - это некоторой тип, а t - это переменная типа T.
Может ли когда-нибудь выражение
C++
1
sizeof(T) != sizeof t
оказаться верным?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.11.2011, 11:53     Нюансы использования оператора sizeof()
Посмотрите здесь:

Нюансы использования оператора запятая или что такое UB и с чем его едят - C++
Почему студия и ideone выдают разные значения для a и b? в студии выходит a = 10 , b = 10 в ideone a = 20, b =10 #include...

Как корректно прервать цикл? (нюансы использования циклов, операторов ветвления и оператора break) - C++
Здравствуйте! такая форма работает...цикл нормально прерывается for(double i=1; i<=10; i++){ if(i==8) break; ...

Работа оператора Sizeof - C++
Каким образом вычисляется размер, допустим, массива int mass ? Где-то в памяти хранится размер, и оператор просто его оттуда вытаскивает,...

Объяснить нюансы использования литералов-перечислителей - C++
Почему в Си не допускается, чтобы один и тот же литерал-перечислитель входил в два различных перечислимых типа? Могут ли совпадать имена...

Нюансы использования операторов new/delete в деструкторах - C++
Подскажите пожалуйста, в чем проблема у меня в деструкторах? Есть 3 класса(по порядку размещения ниже), когда первые 2 удаляются все...

Нюансы синтаксиса и тонкости использования указателей и массивов - C++
Доброго времени суток! Никак не могу понять, почему один вариант кода работает: #include <iostream> #include <stdlib.h> ...

Нюансы использования абстрактных базовых классов (класс Shape) - C++
У меня класс Point наследуется с абстрактного базового класса Shape, и Point тоже абстрактный, поскольку не определил функцию get_area()....

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
thick_int
Заблокирован
21.11.2011, 13:31  [ТС]     Нюансы использования оператора sizeof() #21
Цитата Сообщение от Jupiter Посмотреть сообщение
по умолчанию то что в двойных кавычках имеет тип const char[](потому что мы не может написать вот так
C++
1
"TestStr" = ...
), а символьный массив а просто инициализируется строковым литералом
После чего мы уже ничего не можем записывать в этот массив (во всяком случае простым присваиванием типа
C++
1
a = "Best"
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
21.11.2011, 13:34     Нюансы использования оператора sizeof() #22
Цитата Сообщение от thick_int Посмотреть сообщение
После чего мы уже ничего не можем записывать в этот массив (во всяком случае простым присваиванием типа
присваивать строки нельзя, их можно только копировать, присваивать можно указатели на строковые литералы
Сыроежка
Заблокирован
21.11.2011, 13:57     Нюансы использования оператора sizeof() #23
Цитата Сообщение от thick_int Посмотреть сообщение
Пусть T - это некоторой тип, а t - это переменная типа T.
Может ли когда-нибудь выражение
C++
1
sizeof(T) != sizeof t
оказаться верным?
Нет, не может! Память любому объекту всегда выдеяется на основании его типа. То есть, несколько косноязыча говоря, память выделяется типу, а затем предоставляется в распоряжение объекта.

Другое дело, что не всегда в выражениях можно заменить sizeof( T ) на siizeof( t ), хотя формально их значения равны.

Например,

C++
1
2
void f( int a, int b = sizeof( a ) );     //  Ошибка: нельзя использовать sizeof( a )
void f( int a, int b = sizeof( int ) );   //  Корректно: значение по умолчанию для параметра b = sizeof( int )
accept
4820 / 3240 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
21.11.2011, 22:28     Нюансы использования оператора sizeof() #24
Цитата Сообщение от thick_int
После чего мы уже ничего не можем записывать в этот массив
сделай a[0] = 'b';
thick_int
Заблокирован
21.11.2011, 23:27  [ТС]     Нюансы использования оператора sizeof() #25
Цитата Сообщение от accept Посмотреть сообщение
сделай a[0] = 'b';
Нет ну так то понятно. Однако и здесь не все так просто.
Например, вот такой вариант
C++
1
2
3
4
char str[5] = "Test";
cout << str << endl;
str[0] = 'B';
cout << str << endl;
проходит

И такой вариант
C++
1
2
3
4
char str[] = "Test";
cout << str << endl;
str[0] = 'B';
cout << str << endl;
тоже проходит

А вот такой уже не проходит
C++
1
2
3
4
char* str = "Test";
cout << str << endl;
str[0] = 'B'; //Здесь ошибка
cout << str << endl;
То есть в данном случае традиционная ассоциация между указателями и массивами слегка подпорчена.
Сыроежка
Заблокирован
21.11.2011, 23:51     Нюансы использования оператора sizeof() #26
Цитата Сообщение от thick_int Посмотреть сообщение
Нет ну так то понятно. Однако и здесь не все так просто.
Например, вот такой вариант
C++
1
2
3
4
char str[5] = "Test";
cout << str << endl;
str[0] = 'B';
cout << str << endl;
проходит

И такой вариант
C++
1
2
3
4
char str[] = "Test";
cout << str << endl;
str[0] = 'B';
cout << str << endl;
тоже проходит

А вот такой уже не проходит
C++
1
2
3
4
char* str = "Test";
cout << str << endl;
str[0] = 'B'; //Здесь ошибка
cout << str << endl;
То есть в данном случае традиционная ассоциация между указателями и массивами слегка подпорчена.
Указатель - это не массив. Просто имеется неявное преобразование в выражениях или при передачи массива в качестве аргумента функции имени массива в указатель на его первый элемент.

В последнем вашем примере, вы объявляете указатель, который указывает на строковый литерал "Test". В С++ строковый литерал имеет тип const char[], поэтому и указатель правильно объявлять как

C++
1
const char *str = "Test";
Просто для совместимости с кодом языка С стандарт С++ разрешает не писать квалификатор const для таких указателей, хотя предупреждает, что в будущем такое послабление может быть отменено стандартом С++, а потому такое объявление указателя без const компиляторами будет рассматриваться как ошибка.
thick_int
Заблокирован
21.11.2011, 23:59  [ТС]     Нюансы использования оператора sizeof() #27
А вот тут я тоже Вас хочу разочаровать.
Тот код, который вроде как не срабатывает
C++
1
2
3
4
char* str = "Test";
cout << str << endl;
str[0] = 'B'; //Здесь ошибка
cout << str << endl;
на самом деле оказывается вполне работоспособным, если его оформить в виде отдельной функции и передать ей соответствующий указатель.
А вот если, объявить переменную str с типом const char*, то тут уже компилятор возмутится на передачу константного объекта в неконстантный параметр.
Ну в смысле, когда Вы менять будете.
Так что здесь иеются свои тонкости.
Сыроежка
Заблокирован
22.11.2011, 00:05     Нюансы использования оператора sizeof() #28
Цитата Сообщение от thick_int Посмотреть сообщение
А вот тут я тоже Вас хочу разочаровать.
Тот код, который вроде как не срабатывает
C++
1
2
3
4
char* str = "Test";
cout << str << endl;
str[0] = 'B'; //Здесь ошибка
cout << str << endl;
на самом деле оказывается вполне работоспособным, если его оформить в виде отдельной функции и передать ей соответствующий указатель.
А вот если, объявить переменную str с типом const char*, то тут уже компилятор возмутится на передачу константного объекта в неконстантный параметр.
Так что здесь иеются свои тонкости.
Вы меня не разочаровали, потому что в отличии от вас я знаю стандарт С++!

Компилятору разрешается литералы помещать в память только для чтения. А потому если вы попытаетесь его изменить, то ваша программа может завершиться аварийно.
То есть попытка изменения строкового литерала согласно стандарту означает неопределенное поведение программы. Что это значит? Что, например, в Windows у вас программа завершится аварийно. А где-то в старом MS-DOS может и пройти такой фокус. Так что никаких "тонкостей" нет. Тонкости состоят лишь в том, что вы с первого раза не поняли, что я первоначально написал. Вот и вся "тонкость".
accept
4820 / 3240 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
22.11.2011, 01:03     Нюансы использования оператора sizeof() #29
Цитата Сообщение от thick_int
А вот такой уже не проходит
C++
1
2
3
4
char* str = "Test";
cout << str << endl;
str[0] = 'B'; //Здесь ошибка
cout << str << endl;
а с чего ему проходить ? указатель на символ и массив символов - разные вещи
в случае с указателем в него записывается один адрес одного символа, даже сам символ в него не записывается, только адрес
(адрес первого символа в цепочке символов, завершающейся нуль-символом, которая находится где угодно в памяти)

вот такая проходит
C++
1
2
3
4
5
char a[] = "Test";
char *str = a;
cout << str << endl;
str[0] = 'B'; //Здесь не ошибка
cout << str << endl;
igelstein
0 / 0 / 0
Регистрация: 14.01.2016
Сообщений: 4
14.01.2016, 19:03     Нюансы использования оператора sizeof() #30
Объясните нубу по поводу sizeof. В литературе данный оператор представлен как средство для обеспечения машинонезависимости, при этом указано, что оператор выполняется на этапе компиляции. Но если я получил ехе-файл на одной машине, а запустил на другой, то каким образом sizeof определит значения типов на новой машине? разве компиляция выполняется при каждом запуске ехе-файла?
hoggy
6369 / 2587 / 452
Регистрация: 15.11.2014
Сообщений: 5,723
Завершенные тесты: 1
14.01.2016, 20:12     Нюансы использования оператора sizeof() #31
Цитата Сообщение от igelstein Посмотреть сообщение
Объясните нубу по поводу sizeof. В литературе данный оператор представлен как средство для обеспечения машинонезависимости, при этом указано, что оператор выполняется на этапе компиляции. Но если я получил ехе-файл на одной машине, а запустил на другой, то каким образом sizeof определит значения типов на новой машине? разве компиляция выполняется при каждом запуске ехе-файла?
что бы получить exe, нужно сначала скомпилировать программу.
после компиляции уже не существует ни sizeof, ни с++.

есть только машинный код - цепочка циферок,
которые понимает центральный процессор.
Croessmah
Модератор
Эксперт CЭксперт С++
12980 / 7292 / 812
Регистрация: 27.09.2012
Сообщений: 18,007
Записей в блоге: 3
Завершенные тесты: 1
14.01.2016, 20:15     Нюансы использования оператора sizeof() #32
Цитата Сообщение от igelstein Посмотреть сообщение
Но если я получил ехе-файл на одной машине, а запустил на другой, то каким образом sizeof определит значения типов на новой машине?
Никак. Ваша программа скомпилирована под определенную архитектуру.
igelstein
0 / 0 / 0
Регистрация: 14.01.2016
Сообщений: 4
14.01.2016, 20:25     Нюансы использования оператора sizeof() #33
Цитата Сообщение от hoggy Посмотреть сообщение
что бы получить exe, нужно сначала скомпилировать программу.
после компиляции уже не существует ни sizeof, ни с++.
Цитата Сообщение от Croessmah Посмотреть сообщение
Никак. Ваша программа скомпилирована под определенную архитектуру.
Вот и я так же рассуждал. А причём тогда здесь машинонезависимость? Или это относится к компиляции в промежуточные "форматы"? когда программа "докомпелируется" при/перед выполнением в виртуальной среде или т.п.?
hoggy
6369 / 2587 / 452
Регистрация: 15.11.2014
Сообщений: 5,723
Завершенные тесты: 1
14.01.2016, 21:20     Нюансы использования оператора sizeof() #34
Цитата Сообщение от igelstein Посмотреть сообщение
Вот и я так же рассуждал. А причём тогда здесь машинонезависимость?
при том, что программа компилируется конкретным компилятором под конкретную платформу.
а не в сферическом вакууме.

на разных платформах размеры типов могут быть разными.
но в исходном коде вам эти различия учитывать не нужно.

sizeof всегда возвращает правильный размер
независмо от платформы и её нюансов.
igelstein
0 / 0 / 0
Регистрация: 14.01.2016
Сообщений: 4
14.01.2016, 21:56     Нюансы использования оператора sizeof() #35
hoggy, т.е. имеется в виду, что трансляция/компиляция проги на языке С++ будет давать идентичные результаты на разных машинах, но гарантированно работоспособными полученные/скомпилированные программы будут только на этих же машинах?
hoggy
6369 / 2587 / 452
Регистрация: 15.11.2014
Сообщений: 5,723
Завершенные тесты: 1
14.01.2016, 22:42     Нюансы использования оператора sizeof() #36
Цитата Сообщение от igelstein Посмотреть сообщение
имеется в виду, что трансляция/компиляция проги на языке С++ будет давать идентичные результаты на разных машинах
нет.
результаты будут соотвествовать машинам
на которых осуществлялась сборка.
и могут не сооотвествовать другим машинам.
Evg
Эксперт CАвтор FAQ
17473 / 5711 / 364
Регистрация: 30.03.2009
Сообщений: 15,683
Записей в блоге: 26
15.01.2016, 10:12     Нюансы использования оператора sizeof() #37
Цитата Сообщение от igelstein Посмотреть сообщение
Объясните нубу по поводу sizeof. В литературе данный оператор представлен как средство для обеспечения машинонезависимости, при этом указано, что оператор выполняется на этапе компиляции. Но если я получил ехе-файл на одной машине, а запустил на другой, то каким образом sizeof определит значения типов на новой машине? разве компиляция выполняется при каждом запуске ехе-файла?
В данном случае под словом "машиннонезависимость" на самом деле имеется в виду что-то типа "программные соглашения по размерам типов на конкретной платформе". Допустим, нужно обнулить массив. Если писать так:

C
int a[100];
memset (a, 0, 400);
то такой код будет работать правильно (т.е. по задумке афтора) только на тех платформах (точнее, компиляторах), где размер int'а равен 4 байтам. А если написать вот так:

C
int a[100];
memset (a, 0, 100 * sizeof(int));
то код будет работать корректно на любой платформе, на которой мы скомпилируем данный пример
Croessmah
Модератор
Эксперт CЭксперт С++
12980 / 7292 / 812
Регистрация: 27.09.2012
Сообщений: 18,007
Записей в блоге: 3
Завершенные тесты: 1
15.01.2016, 10:17     Нюансы использования оператора sizeof() #38
Evg, другими словами кроссплатформенность на уровне компиляции (исходного кода).
Evg
Эксперт CАвтор FAQ
17473 / 5711 / 364
Регистрация: 30.03.2009
Сообщений: 15,683
Записей в блоге: 26
15.01.2016, 12:03     Нюансы использования оператора sizeof() #39
Цитата Сообщение от Croessmah Посмотреть сообщение
кроссплатформенность
Кроссплатформенность - слишком широкое понятие. Тут даже не тянет на одну из её составляющих. Даже в рамках одного приложения на одной архитектуре полезно использовать sizeof. Типа того что

C
typedef int ttt;
ttt *p = malloc (n * sizeof (ttt));
или

C
typedef int ttt;
ttt *p = malloc (n * sizeof (*p));
Т.е. завели typedef, и работаем с ним через sizeof, чтобы не держать в голове реальный тип. Не говоря уж о том, что базовый тип typedef'а в какой-то момент может измениться

Добавлено через 2 минуты
Цитата Сообщение от thick_int Посмотреть сообщение
Пусть T - это некоторой тип, а t - это переменная типа T.
Может ли когда-нибудь выражение
sizeof(T) != sizeof t
оказаться верным?
Смотря что тут подразумевается под T: его синтаксическое написание или реальный тип переменной

C
#include <stdio.h>
 
void foo (int a[100])
{
  int b[100];
 
  printf ("%d\n", (int) sizeof(a));
  printf ("%d\n", (int) sizeof(b));
}
 
int main (void)
{
  foo (NULL);
  return 0;
}
Код
$ gcc t.c
$ ./a.out
4
400
Добавлено через 5 минут
Ну или для удобства вот так:

C
#include <stdio.h>
 
typedef int T[100];
 
void foo (T a)
{
  T b;
 
  printf ("%d\n", (int) sizeof(T));
  printf ("%d\n", (int) sizeof(a));
  printf ("%d\n", (int) sizeof(b));
}
 
int main (void)
{
  foo (NULL);
  return 0;
}
Код
$ gcc t.c
$ ./a.out
400
4
400
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.01.2016, 15:14     Нюансы использования оператора sizeof()
Еще ссылки по теме:

Объяснить нюансы использования указателей, массивов и ссылок в функциях - C++
Здравствуйте. Скажите, а что выводит arry значения элемента массива или его адрес? А как понимать что функция возвращает ссылку на int?...

Нюансы использования динамических массивов в качестве данных-членов в классах - C++
Здравствуйте! Не могу создать массив объектов. Помогите ... class hashTable { private: sortedlist* arr ; int arrSize; ...

Нюансы использования исключений: объяснить причины и способы устранения ошибки - C++
Есть такой кусочек кода. Я хочу просмотреть всё что хранится в операционной памяти. Ну и когда я пытаюсь посмотреть что у меня лежит по...

Нюансы синтаксиса: как сравнить каждый элемент массива с переменной в условии оператора if ? - C++
Привет всем дорогие друзья с толкнулся с такой проблемой, начал ходить на уроки с++ и приступил к изучению массива сталкнулся с такой...

Нюансы использования директивы препроцессора #define: найти и исправить ошибки в коде - C++
Добрый день. Помогите, пожалуйста, в решении задачи. Задача простая, но хочется разобраться с #define. У меня есть 3 файла: заголовочный...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
igelstein
0 / 0 / 0
Регистрация: 14.01.2016
Сообщений: 4
15.01.2016, 15:14     Нюансы использования оператора sizeof() #40
Спасибо всем тем, кто помог советом и ответом. Свой затуп осознал
Yandex
Объявления
15.01.2016, 15:14     Нюансы использования оператора sizeof()
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru