C goto 跨越初始化,MinGW-W64 vs MSVC++

标签 c windows visual-c++ mingw-w64

我找到了 here根据 C++ 标准:

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization.

我工作场所的 C 风格编码(我的意思是除了文件扩展名,几乎所有东西都是 C - 没有异常(exception),没有模板,没有实际类)遵守指定的规则here ,即仅在一个地方退出功能,仅在达到完全成功流程时才执行所有权转移,对我们尚未转移所有权的本地人执行清理等。 这是一个小示例(错误代码枚举和为简洁起见省略的其他内容):

int func()
{
    int iStatus = -1;
    PVOID pvSomeData = NULL;
    HANDLE hFile = INVALID_HANDLE_VALUE;

    pvSomeData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BUFFER_SIZE);
    if (nullptr == pvSomeData)
    {
        iStatus = 1;
        goto lblCleanup;
    }

    const PTSTR pszFilePath = _T("C:\\temp\\bla.txt");
    _tprintf(_T("Writing some stuff into '%s'"), pszFilePath);

    hFile = CreateFile(pszFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hFile)
    {
        iStatus = 2;
        goto lblCleanup;
    }

    // do more stuff, fill pvSomeData, write it to the file, transfer ownership, etc.

    // success
    iStatus = 0;

lblCleanup:
    if (INVALID_HANDLE_VALUE != hFile)
    {
        CloseHandle(hFile);
    }
    if (nullptr != pvSomeData)
    {
        HeapFree(GetProcessHeap(), 0, pvSomeData);
    }

    return iStatus;
}

这段 C 风格 代码在 MSVC++ 下编译得很好,但是当试图在 MinGW-W64 下编译它时,编译器提示 goto 语句跨越初始化的问题pszFilePath。 从第一个链接我可以看出,如果我将初始化分为声明和赋值,这将是格式正确的,因为 PWSTR 是 POD 类型。

我想在 MinGW-W64 下编译我的项目而不对我的代码库进行大量修改。有没有办法让我这样做(希望是编译器标志)?

我很清楚在 C++ 中使用 RAII 类对此进行编码的惯用方式,但代码库是扁平的 C 风格线性代码。我也很清楚 goto 在开发人员中引起的强烈反感,以及任何带有 goto 的代码都可以在没有的情况下编写。我要求的不是风格指导,而是解决这个非常具体的问题的最省力的方法。

最佳答案

可能解决此类问题最轻松的方法是引入大括号来限制问题变量的范围,例如更改此 block :

const PTSTR pszFilePath = _T("C:\\temp\\bla.txt");
_tprintf(_T("Writing some stuff into '%s'"), pszFilePath);

hFile = CreateFile(pszFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
    iStatus = 2;
    goto lblCleanup;
}

// do more stuff, fill pvSomeData, write it to the file, transfer ownership, etc.

// success
iStatus = 0;

到:

{
    const PTSTR pszFilePath = _T("C:\\temp\\bla.txt");
    _tprintf(_T("Writing some stuff into '%s'"), pszFilePath);

    hFile = CreateFile(pszFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hFile)
    {
        iStatus = 2;
        goto lblCleanup;
    }

    // do more stuff, fill pvSomeData, write it to the file, transfer ownership, etc.

    // success
    iStatus = 0;
}

关于C goto 跨越初始化,MinGW-W64 vs MSVC++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27005162/

相关文章:

c++ - 模板化的 Pointer 类可以有一个虚拟析构函数吗?

c - 如何在不进行 "/"操作的情况下除以 13

c - 如何向另一台电脑发送通知?

c++ - 没有窗口的 Windows 应用程序中的窗口消息

windows - 是否可以只为 catch block 创建一个函数?

c++ - 从其他专门函数调用专门函数

c - 大数组不会导致堆栈溢出

c - c char** 数组赋值的奇怪行为

c - 为什么片段着色器没有附加?

c++ - 条件预处理难题