Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разница между cout и cerr при вызове исключения, Вопрос о разнице cout и cerr при вызове 
V
    Опции темы
Zerstroer
Дата 10.4.2012, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



Добрый день, столкнулся с такой ситуацией.
Ловил исключения.
Вот так:
Код

    try {
        //здесь выскакивает исключение std::logic_error
    } catch (boost::system::system_error &e){
        cerr << "Boost exception: " << e.code() << endl << e.what() << endl;           
    } catch (exception &e){
        cerr << e.what() << endl;
    }

В процессе открыл для себя следующее:
В случае если в try блоке выскакивает сообщение std::logic_error при попытке в блоке catch вывести сообщение через cout - сообщение не выводится, а выводится только если в cerr выкидываю.
При отлове исключения из boost::system::system_error - все прекрасно выбрасывалось и в cout. 
Возник вопрос - почему?
Почему, если случается исключение std::exception - не срабатывает вывод в cout, а при исключении boost - cout работает?



--------------------
In silico
PM MAIL ICQ   Вверх
borisbn
Дата 10.4.2012, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Какой компилятор ? На MinGW - работает:
http://liveworkspace.org/code/1f6507a03ece...4f994f683c6c7e6


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Zerstroer
Дата 10.4.2012, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



borisbn, компилятор g++ 4:4.4.5


--------------------
In silico
PM MAIL ICQ   Вверх
borisbn
Дата 10.4.2012, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Zerstroer, попробуй запустить в точности такой код:
Код

#include <iostream>
#include <stdexcept>
using namespace std;

int main () {
  try
  {
    throw( logic_error( "throw( logic_error )" ) );
  }
  catch (exception& e)
  {
    cout << "exception caught: " << e.what() << endl;
  }
  return 0;
}

есть подозрение, что в твоём проекте ошибка где-то в другом месте, а на cout/cerr она просто влияет


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Zerstroer
Дата 10.4.2012, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



borisbn, Ваши подозрения оправдались!
Вывод:
Код

exception caught: throw( logic_error )
ВЫПОЛНИТЬ SUCCESSFUL (общее время: 123мс)


Немножко дополняю исходный пример:

Код

 try {
       RS232handler myh;
        //using namespace boost::asio::serial_port_base;
        myh.setConnectParameters(9600, 8, 
                boost::asio::serial_port_base::flow_control::none,
                boost::asio::serial_port_base::parity::none,
                boost::asio::serial_port_base::stop_bits::one,
            argv[1]);
        cout << "Connection result: ";
        cout << myh.connectToPort() << endl;
    } catch (boost::system::system_error &e){
        cerr << "Boost exception: " << e.code() << endl << e.what() << endl;           
    } catch (exception &e){
        cerr << e.what() << endl;
    }


Код метода setConnectParameters:

Код

int RS232handler::setConnectParameters(unsigned int badurate, unsigned int character_size, 
    boost::asio::serial_port_base::flow_control::type flow_control, 
    boost::asio::serial_port_base::parity::type parity, 
    boost::asio::serial_port_base::stop_bits::type stop_bits, 
    const char* port_name){
    connection_parameters.baudrate = badurate;
    connection_parameters.character_size = character_size;
    connection_parameters.flow_control = flow_control;
    connection_parameters.parity = parity;
    connection_parameters.stop_bits = stop_bits;
    connection_parameters.port_name = port_name;
    paramsSet = true;    
}


m_Port в данном случае:

Код

boost::asio::serial_port m_Port;


Код структуры connection_parameters:

Код

struct RS232connectParameters{
        unsigned int baudrate;
        unsigned int character_size;
        boost::asio::serial_port_base::flow_control::type flow_control;
        boost::asio::serial_port_base::parity::type parity;
        boost::asio::serial_port_base::stop_bits::type stop_bits;
        const char* port_name;
    }; 


Код метода connectToPort
Код

int RS232handler::connectToPort(){
    try {      
        m_Port.open(connection_parameters.port_name);
        if(m_Port.is_open())
        {
            m_Port.set_option( boost::asio::serial_port_base::baud_rate( connection_parameters.baudrate ));
            m_Port.set_option( boost::asio::serial_port_base::character_size( connection_parameters.character_size ));
            m_Port.set_option( boost::asio::serial_port_base::flow_control(connection_parameters.flow_control));
            m_Port.set_option( boost::asio::serial_port_base::parity(connection_parameters.parity));
            m_Port.set_option( boost::asio::serial_port_base::stop_bits(connection_parameters.stop_bits));
        }
    } catch (boost::system::system_error &e) {
        std::cerr << "boost exception: " << e.code() << std::endl 
                << e.what() << std::endl;
        throw e;
    } catch (std::logic_error &e) {
        std::cerr << "standart exception: " << e.what() << std::endl;
        throw e;
    }
    return 0;
}


Исключение возникает при вызове метода connectToPort если argv[1] - был пустым. Внутри метода connectToPort - когда там вместо cerr было cout - так же вывод не работал.

Это сообщение отредактировал(а) Zerstroer - 10.4.2012, 13:23


--------------------
In silico
PM MAIL ICQ   Вверх
xvr
Дата 10.4.2012, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Может кто то банально закрыл stdout? (m_Port.open(NULL) например)

PM MAIL   Вверх
Zerstroer
Дата 10.4.2012, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



xvr
Цитата(xvr @  10.4.2012,  11:35 Найти цитируемый пост)
Может кто то банально закрыл stdout? (m_Port.open(NULL) например)

подскажите, как проверить это предположение?
Выполнить m_Port.open(NULL) (вне блока try) и тут же что-нибудь кинуть в cout?


Это сообщение отредактировал(а) Zerstroer - 10.4.2012, 13:55


--------------------
In silico
PM MAIL ICQ   Вверх
borisbn
Дата 10.4.2012, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(xvr @  10.4.2012,  13:35 Найти цитируемый пост)
m_Port.open(NULL) например

ага. похоже

Zerstroer, распечатай argv[1] перед вызовом setConnectParameters


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Zerstroer
Дата 10.4.2012, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



Цитата(borisbn @  10.4.2012,  11:53 Найти цитируемый пост)
 распечатай argv[1] перед вызовом setConnectParameters 


borisbn,   argv[1] - пустой. Я знаю это. Пытаюсь проверить, блокирует ли m_Port.Open(NULL) stdout или нет. 


--------------------
In silico
PM MAIL ICQ   Вверх
Zerstroer
Дата 10.4.2012, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



Какая-то банальщина в итоге получилась.

Код

#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
    cout << "one!" << endl;
    cout << argv[1] << endl;
    cout << "two!" << endl;
    return 0;
}


Если в данном случае argv[1] - пустой - дальнейший вывод через cout - вообще не работает. 
Поясните, как это?
cout << NULL; и cout << argv[1]; (где argv[1] - не существует)- не равнозначны. NULL - cout кушает, как "0" и продолжает дальше работать.
А несуществующий argv[1] блокирует cout? 
Как это можно объяснить с точки зрения памяти?
argv[1] - это не произвольный не занятый фрагмент памяти, а вообще не существующий?





--------------------
In silico
PM MAIL ICQ   Вверх
borisbn
Дата 10.4.2012, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(Zerstroer @  10.4.2012,  14:21 Найти цитируемый пост)
argv[1] - это не произвольный не занятый фрагмент памяти, а вообще не существующий?

несуществующего в Си не бывает. бывает инициализированная, доступная для read/write память и "мусор". куда указывает неинициализированный указатель argv[1] - одному разработчику gcc и создателю твоей ОС известно))

Добавлено через 25 секунд
В общем, проверяй argc и будет щазтье


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Zerstroer
Дата 10.4.2012, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



borisbn, да что его проверять-то... 
я как бы должен его получать из консоли аргументы. 
А если аргумент из консоли не пришел, а в cout я его отправил? 
Почему cout блокируется?
Дурацкий вопрос, конечно. Вы меня извините, интересуюсь ради самообразования.

Это сообщение отредактировал(а) Zerstroer - 10.4.2012, 15:05


--------------------
In silico
PM MAIL ICQ   Вверх
borisbn
Дата 10.4.2012, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Zerstroer, это называется UB
и потом, я тебе говорю не argv проверять, а argc, т.е. количество параметров, переданных тебе из командной строки


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Zerstroer
Дата 10.4.2012, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 8.8.2007
Где: Алма-Ата

Репутация: нет
Всего: 3



Цитата(borisbn @  10.4.2012,  13:08 Найти цитируемый пост)
и потом, я тебе говорю не argv проверять, а argc, т.е. количество параметров, переданных тебе из командной строки 

borisbn, я хотел сказать, что понимаю, что в случае ввода параметров из консоли, их наличие нужно будет проверять. Это понятно.

Меня интересовал сам факт того, что cout << argv[N]; - когда argv[N] - не был получен из консоли, блокирует cout.

Добавлено через 2 минуты и 52 секунды
Если это гарантированно Undefined behavior и иначе это объяснить нельзя, тогда вопросов больше не имею.


--------------------
In silico
PM MAIL ICQ   Вверх
borisbn
Дата 10.4.2012, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Zerstroer, пойми, argv тут совершенно не при чём. это равносильно тому, что написать
Код
int * p = (int*)0xBAADFACE;
cout << p;

то, что на твоём компьютере, на твоей ОС и на твоём компиляторе "блокируется" cout, ещё не означает что при других обстоятельствах ты получишь такое же поведение своей программы. на то это и UB  smile 


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1202 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.