Почему исключение не может быть перехвачено в Windows с помощью msvc, а в Linux - с помощью GCC

Те же файлы в Windows и Linux:

std_exp.cpp

#include <iostream>
#include <string>
#include <stdexcept>

using namespace std;

int main() {
    try {
        std::string s{nullptr};
    } catch (const std::exception &e) {
        std::cerr << "Caught exception: " << e.what() << std::endl;
    }

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(test001)
set(CMAKE_CXX_STANDARD 11)
message(STATUS "C++ compiler: ${CMAKE_CXX_COMPILER}")
message(STATUS "C++ compiler ID: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "C++ compiler version: ${CMAKE_CXX_COMPILER_VERSION}")
add_executable(test001 std_exp.cpp)

Это мои команды компиляции. компилировать команды

cmake -B ./build -S ./
cmake --build ./build/ --config Release

вывод компилятора

On Windows:
-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22000.
-- C++ compiler: ${ROOT_PATH1}/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe
-- C++ compiler ID: MSVC
-- C++ compiler version: 19.40.33812.0
-- Configuring done
-- Generating done
-- Build files have been written to: ${ROOT_PATH2}/build

On Linux:
-- C++ compiler: /usr/bin/c++
-- C++ compiler ID: GNU
-- C++ compiler version: 11.4.0
-- Configuring done
-- Generating done
-- Build files have been written to: ${ROOT_PATH3}/build

Исполняемый вывод в Linux

On Windows:
(no output)
On Linux:
std_exp.cpp15Caught exception: basic_string: construction from null is not valid

Так почему же эксп не ловится на винде?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
112
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Конструктор std::string, который вы пытаетесь использовать, имеет неопределенное поведение, если аргумент на самом деле не является указателем на строку. См. https://en.cppreference.com/w/cpp/string/basic_string/basic_string, в частности перегрузку (9).

Тот факт, что один компилятор выдает исключение, а другой нет, является вполне разумным результатом при неопределенном поведении, как и любое другое поведение вообще.

В качестве примечания: начиная с C++23 существует дополнительная перегрузка (18), которая будет вызывать nullptr в качестве аргумента конструктора std::string неправильного формата.

В документации cppreference фактически упоминается случай использования нулевого указателя для создания std::string в качестве конкретного примера возникновения неопределенного поведения:

Basic_string( const CharT* s, const Allocator& alloc = Allocator() ); (9)

(9) ...
Поведение не определено, если [s, s + Traits::length(s)) не является допустимым. диапазон (например, если s — нулевой указатель).

(выделено мной)

Это именно то, что вы делаете, и, следовательно, это UB (неопределённое поведение), и каждый результат действителен.
В частности, каждый компилятор волен обрабатывать его по своему усмотрению (включая создание исключения или любой другой способ обработки).

cppreference — хороший справочник, но, по моему мнению, называть его «документацией» вводит в заблуждение.

463035818_is_not_an_ai 15.07.2024 10:54

@ 463035818_is_not_an_ai, насколько я понимаю, помимо самого стандарта, считается, что cppreference предлагает лучшую документацию для C++ (именно это я имел в виду). Но в любом случае я обновил и явно упомянул cppreference, чтобы избежать путаницы.

wohlstad 15.07.2024 10:57

@ 463035818_is_not_an_ai Это лучший источник информации о C++, который все еще доступен для чтения большинству пользователей (стандарт C++, хотя и более корректен, не так читабелен, и ему определенно не хватает канонических примеров, которые есть в cppreference). Так что да, я бы тоже посчитал это де-факто документацией для практического использования.

Pepijn Kramer 15.07.2024 11:06

@PepjinKramer «де-факто» все еще не является «документацией». Говоря, что это «документация», подразумевается, что она будет единственной/официальной, чего на самом деле нет. Немного неправильно — это все равно неправильно, и, по моему мнению, это заслуживает лучшего, называть это правильным именем уже достаточно хорошо. Это лучший справочный сайт, который я знаю.

463035818_is_not_an_ai 15.07.2024 11:10

@PepijnKramer Я действительно согласен с 463035818_is_not_an_ai в том, что «документация» подразумевает официальную, поэтому я отредактировал, указав явно cpprefernce. Но мы все согласны, что это лучший справочник на данный момент.

wohlstad 15.07.2024 11:12

Другие вопросы по теме