Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
Заблокирован
1

Поведение оператора new платфоромозависимое?

19.09.2014, 11:04. Показов 2811. Ответов 59
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В случае неудачи оператора new, допустим out of memory, он может кинуть исключение или вернуть ноль:
MSDN:
If unsuccessful, new returns zero or throws an exception
Подскажите, а это поведение так сказать платформ депендет или на всех платформах по дефолту он ведёт себя одинаково. Это же поведение можно поменять ?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.09.2014, 11:04
Ответы с готовыми решениями:

Не понятное поведение тернарного оператора
#include "stdafx.h" #include <initializer_list> #include <iostream> #include <algorithm> int...

Неправильное поведение программы с использованием логического оператора или
while((ch=_getche())!='.') a=a*10+ch-'0'; ch='0'; while((ch=_getche())!='.') b=...

Поясните поведение оператора ==
Почему == возвращает false а Equals true ? Для object a = 2; object b = 2; Я знаю что Equals на...

Необычное поведение оператора инкремента
Добрый день! Это просто несчастье какое-то. Я пытаюсь посчитать коэффициенты корреляции,...

59
Заблокирован
19.09.2014, 15:48  [ТС] 41
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от KOPOJI Посмотреть сообщение
есть set_new_handler
И тут на сцену выходит геморой отлавливания инфы, откуда, с какой строчки кода, в какой процедуре, из какого объекта и тд это исключение дропнулось ... Инфа нужна для лога и для необходимых действий
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
19.09.2014, 16:11 42
Цитата Сообщение от CheshireCat Посмотреть сообщение
Хе-хе. Мы ж находимся в контексте форума по C++, не так ли?
Так ото ж. NULL - это сугубо сишный причендал, и в C++ не используется. Для обозначения нулевого указателя раньше использовался 0, теперь nullptr.
1
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
19.09.2014, 16:14 43
Цитата Сообщение от Mr.X Посмотреть сообщение
Для обозначения нулевого указателя раньше использовался 0,
NULL использовался, и не как тех.реализация а как наглядность для человека.
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
19.09.2014, 16:17 44
Цитата Сообщение от Avazart Посмотреть сообщение
NULL использовался, и не как тех.реализация а как наглядность для человека.
Ну, это только теми, кто Страуструпа не читал или не уважает. Ибо старичок очень не рекомендует.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
19.09.2014, 16:19 45
Ну а Дьюхерст вроде рекомендует и я с ним согласен, ибо вероятность что где то-там NULL будет как то не так определен - мала. А вот ошибиться указатель/не указатель легче.
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
19.09.2014, 16:27 46
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну, это только теми, кто Страуструпа не читал или не уважает. Ибо старичок очень не рекомендует.
Старичок Страуструп, конечно же, человек заслуженный.... Но все же для меня истина в последней инстанции - это текст Стандарта. Ага, 18.2 в последней редакции, или же 18.1 в предыдущей.
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
19.09.2014, 16:38 47
Цитата Сообщение от Avazart Посмотреть сообщение
Ну а Дьюхерст вроде рекомендует и я с ним согласен
Заглянувши в Дьюхерста, увидел там следующее:
"Тем не менее, настоящие программисты на C++ по-прежнему представляют нулевой указатель литералом 0. Применяя любой другой способ, вы рискуете показаться безнадежно старомодным."
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
19.09.2014, 18:27 48
Хз, значит в другой книге видел.
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
19.09.2014, 20:52 49
Цитата Сообщение от CheshireCat Посмотреть сообщение
18.2 в последней редакции, или же 18.1 в предыдущей.
Ага. Там как раз есть интересная сноска:
в 18.3.2.2
197) Possible definitions include 0 and 0L, but not (void*)0.
и еще вот такая в 8.5
107) As specified in 4.10, converting an integer literal whose value is 0 to a pointer type results in a null pointer value.
А вот конкретно про оператор new:
18.6.1.1
Default behavior: Calls operator new(size). If the call returns normally, returns the result of that
call. Otherwise, returns a null pointer.
[Example:
T* p1 = new T; // throws bad_alloc if it fails
T* p2 = new(nothrow) T; // returns 0 if it fails
—end example ]
Битовое же представление указателя вообще не обязано даже выражаться одним числом, не говоря уже про конкретно нулевое значение null pointer.
Стандартом гарантируется, что компилятор знает как преобразовать 0 в правильный null pointer, этого достаточно, чтобы без опаски использовать его (0). Так что слова Страуструпа ни в коем случае не расходятся со стандартом и с реальным положением вещей.

PS. Да, я работал с платформами, где null pointer имеет не равное числовому нулю битовое представление, и в С++ ноль приведенный к указателю принимал правильное значение.
Все вышесказанное относится к С++. В С действительно нужен NULL.

В заключение приведу кусочек GNU libio.h
C
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef NULL
# if defined __GNUG__ && \
(__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
#  define NULL (__null)
# else
#  if !defined(__cplusplus)
#   define NULL ((void*)0)
#  else
#   define NULL (0)
#  endif
# endif
#endif
Добавлено через 1 час 7 минут
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
Ну на счёт предпочтения понял, но всё же, практический выхлоп то от него какой?
nullptr позволяет типизировать null pointer, в С++03 и С++98 использование нуля вот в таком
C++
1
2
3
4
void a(int x);
void a(int * x);
//.....
a(0); // выбор между а(int) и a(int*)
контексте приводило к не всегда ожидаемому эффекту (вызовется перегрузка с int, т.к. она не требует конверсии, если требовалось иное, то приходилось использовать явное приведение).

А уже вот в таком примере мы бы получили ошибку компиляции:
C++
1
2
3
4
void a(long x);
void a(int * x);
//.....
a(0); // выбор между а(long) и a(int *) приводит к ошибке компиляции
Кстати, если бы NULL был определен как ((void*)0), то вот на таком примере мы бы тоже получили ошибку компиляции, хотя, очевидно, по смыслу ее здесь быть не должно.
C++
1
2
3
void a(int *);
//...
a(NULL);
В С++11/14, используя nullptr вместо ноля, мы сможем гарантировать отсутствие таких коллизий.
0
Заблокирован
20.09.2014, 06:27  [ТС] 50
Цитата Сообщение от DrOffset Посмотреть сообщение
А уже вот в таком примере мы бы получили ошибку компиляции:
void a(long x);
void a(int * x);
//.....
a(0); // выбор между а(long) и a(int *) приводит к ошибке компиляции
Честно говоря, я не не первый день знаком с С++ , но никогда не любил перегруженных функций и шаблонные классы ( template class и т.д.), нет, конечно STL то я уважаю, но этого и хватает. Хотя теперь мне и Qt хватает и ни на что другое я вряд ли пересяду, хотя всегда считал WinAPI наиболее качественным и профессиональным средством разработки, правда чисто под windows. Ну это я всё к тому, что мне всякие там выборы компилятором перегруженных функций, когда передаёшь туда ноль, как то по барабану. И можете даже не смеяться по поводу моего не желания использовать перегруженные функции (конечно же иногда я их использую), программирование - такая штука, где можно лет 50 чему то учится, а потом придёт пацан и скажет, что ты всё делаешь не правильно но ты уже ничего не будешь менять и скажешь ему "я слишком стар, чтоб что - то менять, я так уже привык" .
Цитата Сообщение от DrOffset Посмотреть сообщение
В С++11/14, используя nullptr вместо ноля, мы сможем гарантировать отсутствие
таких коллизий.
вообще nullptr я с выходом C++11 сразу стал везде задействовать, может это связанно с тем, что на Qt я перешёл уже во времена C++11, до этого всё время программировал в WinApi, а там был всегда NULL (по этому я и думал, что он оттуда).
Тут то я спрашивал про nullptr_t - который по моему мнению вряд ли где - то находит серьёзное применение , нет ну правда, это же тип нуля, а какой в нём только - то ? Ну вот просто пример void Hello(std::nullptr_t);, ну и что? Накой хрен писать процедуру, которая может принимать параметр только ноль? Я проще напишу void Hello(int a); и буду проверять его на ноль
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
20.09.2014, 12:24 51
Введение типа std::nullptr_t нужно для того, чтобы при наличии таких перегрузок:
C++
1
2
void f(int);
void f(T*);
можно было вызвать именно версию с указателем (а не с целым), передавая "нулевой указатель":
C++
1
2
3
4
f(NULL); // вызовет f(int), хотя программист вероятно хотел бы f(T*)
f(nullptr); // вызовет f(T*)
f(static_cast<T*>(NULL)); // тоже вызовет f(T*), но усложняет запись
f((T*)NULL); // f(T*) C-style. Снова лишние движения, о которых надо еще и не забыть.
Т.о. суть введения типа std::nullptr_t не в том, чтобы писать перегруженные функции, которые принимают этот тип, а чтобы вызывалась версия, принимающая указатель, а не целое.
Достигается это тем, что тип nullptr_t (когда передается объект nullptr) может быть неявно преобразован в любой указатель, но не в целое.
0
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
20.09.2014, 12:46 52
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
Честно говоря, я не не первый день знаком с С++ , но никогда не любил перегруженных функций и шаблонные классы ( template class и т.д.), нет, конечно STL то я уважаю, но этого и хватает. Хотя теперь мне и Qt хватает и ни на что другое я вряд ли пересяду, хотя всегда считал WinAPI наиболее качественным и профессиональным средством разработки, правда чисто под windows. Ну это я всё к тому, что мне всякие там выборы компилятором перегруженных функций, когда передаёшь туда ноль, как то по барабану. И можете даже не смеяться по поводу моего не желания использовать перегруженные функции (конечно же иногда я их использую), программирование - такая штука, где можно лет 50 чему то учится, а потом придёт пацан и скажет, что ты всё делаешь не правильно но ты уже ничего не будешь менять и скажешь ему "я слишком стар, чтоб что - то менять, я так уже привык" .
Весь этот пассаж есть следствие того, что ты не понял, о чем я говорил. Вот Tulosba еще раз обозначил эту мысль (спасибо ему). Других веских причин для введения nullptr с собственным типом - нет. Все мои примеры с перегрузками были иллюстрацией этой проблемы (проблемы нетипизированного нулевого указателя), никаких других смыслов в эти примеры я не вкладывал.
И поверь, мне абсолютно по барабану используешь ты перегруженные функции или нет
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
20.09.2014, 14:32 53
Цитата Сообщение от DrOffset Посмотреть сообщение
Других веских причин для введения nullptr с собственным типом - нет.
Ну как это нет? Вот еще два:
1)
C++
1
2
auto result = SomeComplexFunction();
if (result == 0) { // ...
Я смотрю на этот код и не понимаю, что возвращает функция.
C++
1
2
auto result = SomeComplexFunction();
if (result == nullptr) { // ...
А так понимаю.

2) Вывод типов шаблонов работает неверно для 0 и для NULL. Выводится, ну например, int. А для nullptr верно - выводится nullptr_t.

Например. Я хочу написать функцию, которая вначале что-то лочит, а потом вызывает другую функцию, передавая ей указатель на данные. Будет это выглядеть как-то так:
C++
1
2
3
4
5
6
template <typename FuncType, typename MuxType, typename PtrType>
decltype(auto) LockAndCall(FuncType func, MuxType & mutex, PtrType ptr)
{
    MuxGuard g(mutex);
    return func(ptr);
}
И есть у меня скажем вот такие функции, которые я хочу туда передавать:
C++
1
2
3
int f1(std::shared_ptr<SomeType>);
int f2(std::unique_ptr<SomeType>);
int f3(SomeType *);
Тогда следующие вызовы будут выдавать ошибки компиляции:
C++
1
2
LockAndCall(f1, m, 0);
LockAndCall(f2, m, NULL);
Потому что PtrType будет выведен, к примеру, типу int, а неявного преобразования из int в те указатели нету.

В то же время со следующим вызовом все окей:
C++
1
LockAndCall(f3, m, nullptr);
PtrType будет nullptr_t, а для nullptr_t определены неявные преобразования во все вышеперечисленные типы указателей.
2
18842 / 9841 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
20.09.2014, 14:56 54
Цитата Сообщение от ct0r Посмотреть сообщение
auto result = SomeComplexFunction();
Я сейчас выражу свое собственное мнение. Auto чрезвычайно вредная вещь в неопытных руках и использовать ее надо с большой осторожностью. В частности, ИМХО, вот этот пример, с возвратом указателя замаскированным auto - пример неудачного использования. Хотя с сутью я согласен, показать что производится сравнение именно с указателем - хороший case.

Вообще же, ты слишком буквально понял мой пост, все твои примеры, собственно, того же разлива, что и и мои примеры в перегрузкой (я просто не стал это разжевывать - выходит зря).
Все это в итоге достигается введением конверсии из nullptr_t -> some ptr type, вместо прежней int -> some ptr type. Все примеры (и твои и мои) - это лишь демонстрация этого эффекта и показывают, суть, эту конверсию. Именно это я и имел в виду под
Цитата Сообщение от DrOffset Посмотреть сообщение
Других веских причин для введения nullptr с собственным типом - нет
, а не конкретно перегрузки.

Добавлено через 3 минуты
Скажем так, читать это надо было так:
Цитата Сообщение от Tulosba Посмотреть сообщение
тип nullptr_t (когда передается объект nullptr) может быть неявно преобразован в любой указатель, но не в целое.
Цитата Сообщение от DrOffset Посмотреть сообщение
Других веских причин для введения nullptr с собственным типом - нет.
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
20.09.2014, 14:58 55
Цитата Сообщение от DrOffset Посмотреть сообщение
Вообще же, ты слишком буквально понял мой пост, все твои примеры, собственно, того же разлива, что и и мои примеры в перегрузкой (я просто не стал это разжевывать - выходит зря).
По сути да, но контексты немного разные. Тогда скажем так: я показал практический пример, где фигня с int и nullptr_t происходит не только с перегрузкой функций.
0
DrOffset
20.09.2014, 15:00
  #56

Не по теме:

Цитата Сообщение от ct0r Посмотреть сообщение
Скажем так: я показал, что фигня с int и nullptr_t не ограничивается только перегрузкой функций, как кто-то может подумать.
Хорошо. Я согласен, что твое дополнение уместно. Поставлю плюс. :)

0
Убежденный
20.09.2014, 15:13
  #57

Не по теме:


Цитата Сообщение от DrOffset Посмотреть сообщение
Auto чрезвычайно вредная вещь в неопытных руках и использовать ее надо с большой осторожностью.
Приятно знать, что я не одинок :)

P.S. Вместо 'Auto' можно вставить любую конструкцию из C++.
А может и сам C++.

0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
20.09.2014, 15:40 58
Цитата Сообщение от ct0r Посмотреть сообщение
Я смотрю на этот код и не понимаю, что возвращает функция.
Ну дак имя функции должно сообщать об этом. Если же имена функций будут скрывать, а не прояснять их поведение, то никто ничего не поймет, сколько нульпойнтеров туда ни напихай.
1
Заблокирован
20.09.2014, 18:59  [ТС] 59
По моему вот это бред (в Qt)
C++ (Qt)
1
2
3
4
foreach(auto hzChto, container)
    {
        //nu i chto tut hzChto ? IntelliSence daze ne podskazet
    }
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
20.09.2014, 22:33 60
Scrooge McDuck, intellisense это патентованое от ms, которое работает в студии. Креатор не может, потому что не дорос еще.
0
20.09.2014, 22:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.09.2014, 22:33
Помогаю со студенческими работами здесь

Странное поведение оператора сравнения
Доброго всем времени суток. Есть у меня такой вот скрипт: function access(button) { var expert...

Поведение оператора echo при вызове функций
Здравствуйте, заметил вот такое поведение: function foo() { echo 'hello'; } echo foo();...

Непонятное поведение поведение TIM6 на STM32f4discovery
Вводные данные: SYSCLK=168Мгц; AHB Pressotir=1; APB1 Pressotir=4; TIM6_Pessotir=3; Т.о....

Избыточное копирование объекта при реализации оператора умножения и оператора присваивания
Есть класс работы с матрицами. Есть операция умножения матриц, описанная как оператор класса. В...

Неправильная работа оператора присваивания после работы оператора суммирования
Доброго времени суток. У меня есть класс вектор class TVector {//ewde public: TVector();...

Найти матрицу оператора сопряжённого для данного линейного оператора
Здравствуйте! Подскажите мне, пожалуйста, как делать данную задачу: Матрица линейного оператора...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru