2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
1

Switch по указателю

10.07.2017, 13:38. Показов 1780. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть функция которая может вернуть указатель на результат в случае успеха, вернуть nullptr в случае провала, а может выдать критический сбой. Да, я в курсе что для обработки критического сбоя есть исключения или errno. Но мне тут вдруг подумалось что вместо установки errno, можно вернуть указатель на errorObject. Вопрос - можно ли как-то реализовать switch по результату такой функции?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
const char errorObject=0;
const char*function(){return &errorObject;}
int main()
{
    const char*res=function();
    switch(std::uintptr_t(res))
    {
    case std::uintptr_t(nullptr)://так прокатывает
        std::cout<<"data not found"<<std::endl;
        break;
    case std::uintptr_t(&errorObject)://а вот так не прокатывает
        std::cout<<"critical error"<<std::endl;
        break;
    default:
        std::cout<<res<<std::endl;
    }
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.07.2017, 13:38
Ответы с готовыми решениями:

Switch . Как присвоить переменной значение из Switch в default
Добрый день подскажите как реализуется данный код . Как взять значение switch если выпал default ? ...

Как сделать чтобы Switch работал в другом Switch'e?
Как сделать что бы Switch работал в другом Switch'e? Вот допустим выбираем один пункт и в...

Рефакторинг switch внутри switch в static классе
Добрый день. Подскажите, как корректно обойти конструкцию switch case внутри switch case в...

Подключить switch к другому switch
Ребята у меня такая просьба. У меня сеть на 10 компьютеров они все подключены через switch, но мне...

15
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
10.07.2017, 16:32 2
Renji, не думаю, что такое возможно. В switch-case нужно константное выражение, а тут адрес переменной.
Если сделать указатель constexpr, то тогда непонятно, на что он должен указывать и как различить его с корректным результатом.
0
Заблокирован
10.07.2017, 16:40 3
Цитата Сообщение от gray_fox Посмотреть сообщение
В switch-case нужно константное выражение, а тут адрес переменной.
Адрес глобальной (выражаясь простым языком) переменной! Вполне себе константное выражение. Можно в нетиповые параметры темплейтов подставлять.
1
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
10.07.2017, 17:14 4
Renji, хотя может как-нибудь так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include <cstdint>
 
constexpr std::uintptr_t errorValue = 0x1;
const char*function(){return reinterpret_cast<char const*>(errorValue);}
int main()
{
    const char*res=function();
    switch(std::uintptr_t(res))
    {
    case std::uintptr_t(nullptr)://так прокатывает
        std::cout<<"data not found"<<std::endl;
        break;
    case errorValue://а вот так не прокатывает
        std::cout<<"critical error"<<std::endl;
        break;
    default:
        std::cout<<res<<std::endl;
    }
    return 0;
}
Но, честно говоря не уверен, что такие финты законны.

Добавлено через 2 минуты
Цитата Сообщение от daun-autist Посмотреть сообщение
Адрес глобальной (выражаясь простым языком) переменной!
Да, может быть и так.

Добавлено через 30 минут
Цитата Сообщение от gray_fox Посмотреть сообщение
Да, может быть и так.
Хотя нет, так или иначе выражение константное, и reinterpet_cast там неполучится использовать.
1
Заблокирован
10.07.2017, 17:17 5
Цитата Сообщение от gray_fox Посмотреть сообщение
Хотя нет, так или иначе выражение константное, и reinterpet_cast там неполучится использовать.
Это уже другой вопрос. А сам адрес — константное выражение.
1
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
10.07.2017, 19:17 6
Renji, вообще, сама идея выглядит как жуткий костыль, почему бы не использовать std::pair<T *, bool> или optional<T *>, например?
0
Вездепух
Эксперт CЭксперт С++
11693 / 6372 / 1723
Регистрация: 18.10.2014
Сообщений: 16,056
10.07.2017, 20:40 7
Цитата Сообщение от daun-autist Посмотреть сообщение
Адрес глобальной (выражаясь простым языком) переменной! Вполне себе константное выражение. Можно в нетиповые параметры темплейтов подставлять.
Да, но все равно адрес глобальной переменной, приведенный к целочисленному типу, не порождает целочисленного константного выражения.

На самом деле константность адреса глобальной переменной - константность чисто концептуальная. Он на самом деле физически совсем не константен и чтобы изобразить его "константность" компилятору приходится предпринимать недюжинные усилия. Но вот сделать еще и результат приведения к целочисленному типу целочисленным константным выражением - это уже за гранью возможного.
1
Заблокирован
10.07.2017, 20:46 8
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
адрес глобальной переменной, приведенный к целочисленному типу, не порождает целочисленного констатного выражения.
А обратное я и не собираюсь утверждать.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Понятно, что констатность адреса глобальной переменной - понятие чисто концептуальное.
Я знаю, что обычно линкер подставляет адреса.
0
Вездепух
Эксперт CЭксперт С++
11693 / 6372 / 1723
Регистрация: 18.10.2014
Сообщений: 16,056
10.07.2017, 20:48 9
Цитата Сообщение от daun-autist Посмотреть сообщение
Я знаю, что обычно линкер подставляет адреса.
Более того, в случае использования shared objects эти адреса могут стать известными только на стадии загрузки. Спецификация языка была заранее подогнана под то, что умеет делать загрузчик, а что не умеет.
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
10.07.2017, 21:09  [ТС] 10
Цитата Сообщение от gray_fox Посмотреть сообщение
Renji, вообще, сама идея выглядит как жуткий костыль, почему бы не использовать std::pair<T *, bool> или optional<T *>, например?
И вместе if(res==&errorObject), будет if(!res.second). Как по мне, так читаемость только упала. А еще ведь исполняемый код для возврата структуры будет однозначно сложнее.
Собственно, если тащить отдельный флаг ошибок, то есть сишное глобальное errno специально для передачи кодов ошибок и придуманное. Мне же было интересно и код ошибки вернуть, и отдельную переменную под это не тратить.
0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
10.07.2017, 21:19 11
Цитата Сообщение от Renji Посмотреть сообщение
Мне же было интересно и код ошибки вернуть, и отдельную переменную под это не тратить.
Ну без отдельной переменной вряд ли получится. А по поводу читаемости с optional, теоретически, получше, например:
C++
1
2
3
4
5
6
7
8
9
if (auto res = function()) {
   if (*res) {
      // ...
   } else {
      std::cout << "Data not found" << std::endl;
   }
} else {
   std::cerr << "Critical error" << std::endl
}
Хотя, разница, конечно, не большая.
0
Заблокирован
10.07.2017, 21:21 12
Цитата Сообщение от gray_fox Посмотреть сообщение
if (*res)
Может просто if (res)? А то тут такое есть:
Цитата Сообщение от http://en.cppreference.com/w/cpp/utility/optional/operator*
The behavior is undefined if *this does not contain a value.
0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
10.07.2017, 21:29 13
Цитата Сообщение от daun-autist Посмотреть сообщение
Может просто if (res)?
Я имел в виду optional<T *> function(...).
Или я тебя не понял.
0
Заблокирован
10.07.2017, 21:31 14
gray_fox, а зачем тут вообще optional тогда, если отсутствие значения кодируется нулевым указателем? optional имеет смысл использовать когда он сам может не содержать значения.
0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
10.07.2017, 21:32 15
Цитата Сообщение от daun-autist Посмотреть сообщение
gray_fox, а зачем тут вообще optional тогда, если отсутствие значения кодируется нулевым указателем?
Там есть ещё "критический сбой":
Цитата Сообщение от Renji Посмотреть сообщение
функция которая может вернуть указатель на результат в случае успеха, вернуть nullptr в случае провала, а может выдать критический сбой.
0
Заблокирован
10.07.2017, 21:34 16
gray_fox, прозевал, что optional проверяется до разыменования. В общем, never mind.
0
10.07.2017, 21:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.07.2017, 21:34
Помогаю со студенческими работами здесь

Power Switch и Reset Switch
Здравствуйте. Покажите мне пожалуйста на этой материнской плате где находится power switch пин и...

Изменить cell.accessorytype тип на тип Switch (с кнопкой Switch)
Добрый день! 1) не могу понять как сделать кастомный тип ячейки в tableview что бы в нем был...

Поместить switch в switch
Всем привет. Есть работающий код который обрабатывает строку GET и берет от туда данные Вот урл...

Оптимальная конструкция switch-case-while / while-switch-case
Имеется конструкция типа: switch() { case 1: while() { ... }


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

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