Aracılığıyla paylaş


/ZC:implicitNoexcept (Örtük Özel Durum Tanımlayıcıları)

/Zc:implicitNoexcept seçeneği belirtildiğinde, derleyici tarafından tanımlanan özel üye işlevlerine ve kullanıcı tanımlı yıkıcılara ve serbest bırakıcılara örtük bir noexcept özel durum tanımlayıcısı ekler. Varsayılan olarak, /Zc:implicitNoexcept ISO C++11 standardına uyacak şekilde etkinleştirilir. Bu seçeneğin kapatılması, kullanıcı tanımlı yıkıcılar ve serbest bırakıcılar ile derleyici tanımlı özel üye işlevlerini örtük noexcept olarak devre dışı bırakır.

Sözdizimi

/Zc:implicitNoexcept[-]

Açıklamalar

/Zc:implicitNoexcept derleyiciye ISO C++11 standardının 15.4. bölümünü izlemesini söyler. Her örtük olarak bildirilen veya açıkça varsayılan olarak varsayılan özel üye işlevine (varsayılan oluşturucu, kopya oluşturucu, taşıma oluşturucu, yıkıcı, kopya atama işleci veya taşıma atama işleci) ve her kullanıcı tanımlı yıkıcı veya serbest bırakıcı işlevine örtük olarak bir noexcept özel durum tanımlayıcısı ekler. Kullanıcı tanımlı bir serbest bırakıcının örtük noexcept(true) bir özel durum tanımlayıcısı vardır. Kullanıcı tanımlı yıkıcılar için, kapsanan bir üye sınıfı veya temel sınıfın olmayan noexcept(true)bir yıkıcısı olmadığı sürece örtük özel durum tanımlayıcısı noexcept(true) kullanılır. Derleyici tarafından oluşturulan özel üye işlevleri için, bu işlev tarafından doğrudan çağrılan herhangi bir işlev etkili bir şekilde noexcept(false)ise, örtük özel durum tanımlayıcısı olur noexcept(false). Aksi takdirde, örtük özel durum tanımlayıcısı şeklindedir noexcept(true).

Derleyici, açık noexcept veya tanımlayıcılar ya da throw bir öznitelik kullanılarak bildirilen işlevler için örtük bir __declspec(nothrow) özel durum tanımlayıcısı oluşturmaz.

Varsayılan olarak, /Zc:implicitNoexcept etkindir. /permissive- seçeneği /Zc:implicitNoexcept'i etkilemez.

/Zc:implicitNoexcept- belirtilerek seçenek devre dışı bırakılırsa, derleyici tarafından örtük özel durum tanımlayıcısı oluşturulmaz. Bu davranış Visual Studio 2013 ile aynıdır; burada özel durum tanımlayıcıları olmayan yıkıcılar ve serbest bırakıcılar deyimlere sahip throw olabilir. Varsayılan olarak ve /Zc:implicitNoexcept belirtildiğinde, örtük noexcept(true) tanımlayıcısı olan bir işlevde çalışma zamanında bir deyimle karşılaşılırsathrow, hemen çağrısına std::terminateneden olur ve özel durum işleyicileri için normal geri alma davranışı garanti edilemez. Derleyici, bu durumun tanımlanmasına yardımcı olmak için Derleyici Uyarısı (düzey 1) C4297 oluşturur. throw kasıtlıysa, /Zc:implicitNoexcept- kullanmak yerine işlev bildiriminizi açık noexcept(false) bir tanımlayıcıya sahip olacak şekilde değiştirmenizi öneririz.

Bu örnek, /Zc:implicitNoexcept seçeneği ayarlandığında veya devre dışı bırakıldığında, açık özel durum tanımlayıcısı olmayan kullanıcı tanımlı bir yıkıcının nasıl davrandığını gösterir. Ayarlanırken davranışı göstermek için kullanarak cl /EHsc /W4 implicitNoexcept.cppderleyin. Devre dışı bırakıldığında davranışı göstermek için kullanarak cl /EHsc /W4 /Zc:implicitNoexcept- implicitNoexcept.cppderleyin.

// implicitNoexcept.cpp
// Compile by using: cl /EHsc /W4 implicitNoexcept.cpp
// Compile by using: cl /EHsc /W4 /Zc:implicitNoexcept- implicitNoexcept.cpp

#include <iostream>
#include <cstdlib>      // for std::exit, EXIT_FAILURE, EXIT_SUCCESS
#include <exception>    // for std::set_terminate

void my_terminate()
{
    std::cout << "Unexpected throw caused std::terminate" << std::endl;
    std::cout << "Exit returning EXIT_FAILURE" << std::endl;
    std::exit(EXIT_FAILURE);
}

struct A {
    // Explicit noexcept overrides implicit exception specification
    ~A() noexcept(false) {
        throw 1;
    }
};

struct B : public A {
    // Compiler-generated ~B() definition inherits noexcept(false)
    ~B() = default;
};

struct C {
    // By default, the compiler generates an implicit noexcept(true)
    // specifier for this user-defined destructor. To enable it to
    // throw an exception, use an explicit noexcept(false) specifier,
    // or compile by using /Zc:implicitNoexcept-
    ~C() {
        throw 1; // C4297, calls std::terminate() at run time
    }
};

struct D : public C {
    // This destructor gets the implicit specifier of its base.
    ~D() = default;
};

int main()
{
    std::set_terminate(my_terminate);

    try
    {
        {
            B b;
        }
    }
    catch (...)
    {
        // exception should reach here in all cases
        std::cout << "~B Exception caught" << std::endl;
    }
    try
    {
        {
            D d;
        }
    }
    catch (...)
    {
        // exception should not reach here if /Zc:implicitNoexcept
        std::cout << "~D Exception caught" << std::endl;
    }
    std::cout << "Exit returning EXIT_SUCCESS" << std::endl;
    return EXIT_SUCCESS;
}

Varsayılan /Zc:implicitNoexcept ayarı kullanılarak derlendiğinde örnek şu çıkışı oluşturur:

~B Exception caught
Unexpected throw caused std::terminate
Exit returning EXIT_FAILURE

/Zc:implicitNoexcept- ayarı kullanılarak derlendiğinde örnek şu çıkışı oluşturur:

~B Exception caught
~D Exception caught
Exit returning EXIT_SUCCESS

Visual C++'daki uyumluluk sorunları hakkında daha fazla bilgi için bkz . Standart Dışı Davranış.

Bu derleyici seçeneğini Visual Studio geliştirme ortamında ayarlamak için

  1. Projenin Özellik Sayfaları iletişim kutusunu açın. Ayrıntılar için bkz . Visual Studio'da C++ derleyicisi ve derleme özelliklerini ayarlama.

  2. Yapılandırma Özellikleri>C/C++>Komut Satırı özellik sayfasını seçin.

  3. Ek Seçenekler özelliğini /Zc:implicitNoexcept veya /Zc:implicitNoexcept- içerecek şekilde değiştirin ve tamam'ı seçin.

Ayrıca bkz.

/Zc (Uyumluluk)
noexcept
Özel Durum Belirtimleri (throw)
Sonlandır