isprint('\ t')使用/ MD编译器选项求值为true(64)

Mei*_*bur 4 c visual-c++

isprint在Visual Studio 2017下有一个意外的结果.给出以下程序

#include <ctype.h>
#include <stdio.h>

int main() {
  for (int i = 0; i < 128; i += 1) {
    printf("isprint(0x%x aka '%c') = %s (%d)\n", i, (char)i,
           isprint((char)i) ? "yes" : "no", isprint((char)i));
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用编译和执行

cl /MD isprint.c /Feisprint.exe && isprint.exe
Run Code Online (Sandbox Code Playgroud)

回报

Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26433 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

isprint.c
Microsoft (R) Incremental Linker Version 14.14.26433.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:isprint.exe
isprint.obj
isprint(0x0 aka ' ') = no (0)
isprint(0x1 aka '') = no (0)
isprint(0x2 aka '') = no (0)
isprint(0x3 aka '') = no (0)
isprint(0x4 aka '') = no (0)
isprint(0x5 aka '') = no (0)
isprint(0x6 aka '') = no (0)
isprint(0x7 aka '') = no (0)
isprint(0x8 aka ') = no (0)
isprint(0x9 aka '       ') = yes (64)
isprint(0xa aka '
') = no (0)
isprint(0xb aka '') = no (0)
isprint(0xc aka '') = no (0)
') = no (0) aka '
isprint(0xe aka '') = no (0)
isprint(0xf aka '') = no (0)
isprint(0x10 aka '') = no (0)
isprint(0x11 aka '') = no (0)
isprint(0x12 aka '') = no (0)
isprint(0x13 aka '') = no (0)
isprint(0x14 aka '') = no (0)
isprint(0x15 aka '') = no (0)
isprint(0x16 aka '') = no (0)
isprint(0x17 aka '') = no (0)
isprint(0x18 aka '') = no (0)
isprint(0x19 aka '') = no (0)
isprint(0x1a aka '') = no (0)
isprint(0x1b aka '') = no (0)
isprint(0x1c aka '') = no (0)
isprint(0x1d aka '') = no (0)
isprint(0x1e aka '') = no (0)
isprint(0x1f aka '') = no (0)
isprint(0x20 aka ' ') = yes (64)
isprint(0x21 aka '!') = yes (16)
isprint(0x22 aka '"') = yes (16)
isprint(0x23 aka '#') = yes (16)
isprint(0x24 aka '$') = yes (16)
isprint(0x25 aka '%') = yes (16)
isprint(0x26 aka '&') = yes (16)
isprint(0x27 aka ''') = yes (16)
isprint(0x28 aka '(') = yes (16)
isprint(0x29 aka ')') = yes (16)
isprint(0x2a aka '*') = yes (16)
isprint(0x2b aka '+') = yes (16)
isprint(0x2c aka ',') = yes (16)
isprint(0x2d aka '-') = yes (16)
isprint(0x2e aka '.') = yes (16)
isprint(0x2f aka '/') = yes (16)
isprint(0x30 aka '0') = yes (4)
isprint(0x31 aka '1') = yes (4)
isprint(0x32 aka '2') = yes (4)
isprint(0x33 aka '3') = yes (4)
isprint(0x34 aka '4') = yes (4)
isprint(0x35 aka '5') = yes (4)
isprint(0x36 aka '6') = yes (4)
isprint(0x37 aka '7') = yes (4)
isprint(0x38 aka '8') = yes (4)
isprint(0x39 aka '9') = yes (4)
isprint(0x3a aka ':') = yes (16)
isprint(0x3b aka ';') = yes (16)
isprint(0x3c aka '<') = yes (16)
isprint(0x3d aka '=') = yes (16)
isprint(0x3e aka '>') = yes (16)
isprint(0x3f aka '?') = yes (16)
isprint(0x40 aka '@') = yes (16)
isprint(0x41 aka 'A') = yes (1)
isprint(0x42 aka 'B') = yes (1)
isprint(0x43 aka 'C') = yes (1)
isprint(0x44 aka 'D') = yes (1)
isprint(0x45 aka 'E') = yes (1)
isprint(0x46 aka 'F') = yes (1)
isprint(0x47 aka 'G') = yes (1)
isprint(0x48 aka 'H') = yes (1)
isprint(0x49 aka 'I') = yes (1)
isprint(0x4a aka 'J') = yes (1)
isprint(0x4b aka 'K') = yes (1)
isprint(0x4c aka 'L') = yes (1)
isprint(0x4d aka 'M') = yes (1)
isprint(0x4e aka 'N') = yes (1)
isprint(0x4f aka 'O') = yes (1)
isprint(0x50 aka 'P') = yes (1)
isprint(0x51 aka 'Q') = yes (1)
isprint(0x52 aka 'R') = yes (1)
isprint(0x53 aka 'S') = yes (1)
isprint(0x54 aka 'T') = yes (1)
isprint(0x55 aka 'U') = yes (1)
isprint(0x56 aka 'V') = yes (1)
isprint(0x57 aka 'W') = yes (1)
isprint(0x58 aka 'X') = yes (1)
isprint(0x59 aka 'Y') = yes (1)
isprint(0x5a aka 'Z') = yes (1)
isprint(0x5b aka '[') = yes (16)
isprint(0x5c aka '\') = yes (16)
isprint(0x5d aka ']') = yes (16)
isprint(0x5e aka '^') = yes (16)
isprint(0x5f aka '_') = yes (16)
isprint(0x60 aka '`') = yes (16)
isprint(0x61 aka 'a') = yes (2)
isprint(0x62 aka 'b') = yes (2)
isprint(0x63 aka 'c') = yes (2)
isprint(0x64 aka 'd') = yes (2)
isprint(0x65 aka 'e') = yes (2)
isprint(0x66 aka 'f') = yes (2)
isprint(0x67 aka 'g') = yes (2)
isprint(0x68 aka 'h') = yes (2)
isprint(0x69 aka 'i') = yes (2)
isprint(0x6a aka 'j') = yes (2)
isprint(0x6b aka 'k') = yes (2)
isprint(0x6c aka 'l') = yes (2)
isprint(0x6d aka 'm') = yes (2)
isprint(0x6e aka 'n') = yes (2)
isprint(0x6f aka 'o') = yes (2)
isprint(0x70 aka 'p') = yes (2)
isprint(0x71 aka 'q') = yes (2)
isprint(0x72 aka 'r') = yes (2)
isprint(0x73 aka 's') = yes (2)
isprint(0x74 aka 't') = yes (2)
isprint(0x75 aka 'u') = yes (2)
isprint(0x76 aka 'v') = yes (2)
isprint(0x77 aka 'w') = yes (2)
isprint(0x78 aka 'x') = yes (2)
isprint(0x79 aka 'y') = yes (2)
isprint(0x7a aka 'z') = yes (2)
isprint(0x7b aka '{') = yes (16)
isprint(0x7c aka '|') = yes (16)
isprint(0x7d aka '}') = yes (16)
isprint(0x7e aka '~') = yes (16)
isprint(0x7f aka '') = no (0)
Run Code Online (Sandbox Code Playgroud)

问题是它为制表符字符('\t')返回true(64 ).但是,在编译时没有/MD编译器选项或其他一些运行时库版本

cl /MDd isprint.c /Feisprint.exe && isprint.exe
Run Code Online (Sandbox Code Playgroud)

结果是

Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26433 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

isprint.c
Microsoft (R) Incremental Linker Version 14.14.26433.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:isprint.exe
isprint.obj
isprint(0x0 aka ' ') = no (0)
isprint(0x1 aka '') = no (0)
isprint(0x2 aka '') = no (0)
isprint(0x3 aka '') = no (0)
isprint(0x4 aka '') = no (0)
isprint(0x5 aka '') = no (0)
isprint(0x6 aka '') = no (0)
isprint(0x7 aka '') = no (0)
isprint(0x8 aka ') = no (0)
isprint(0x9 aka '       ') = no (0)
isprint(0xa aka '
') = no (0)
isprint(0xb aka '') = no (0)
isprint(0xc aka '') = no (0)
') = no (0) aka '
isprint(0xe aka '') = no (0)
isprint(0xf aka '') = no (0)
isprint(0x10 aka '') = no (0)
isprint(0x11 aka '') = no (0)
isprint(0x12 aka '') = no (0)
isprint(0x13 aka '') = no (0)
isprint(0x14 aka '') = no (0)
isprint(0x15 aka '') = no (0)
isprint(0x16 aka '') = no (0)
isprint(0x17 aka '') = no (0)
isprint(0x18 aka '') = no (0)
isprint(0x19 aka '') = no (0)
isprint(0x1a aka '') = no (0)
isprint(0x1b aka '') = no (0)
isprint(0x1c aka '') = no (0)
isprint(0x1d aka '') = no (0)
isprint(0x1e aka '') = no (0)
isprint(0x1f aka '') = no (0)
isprint(0x20 aka ' ') = yes (64)
isprint(0x21 aka '!') = yes (16)
isprint(0x22 aka '"') = yes (16)
isprint(0x23 aka '#') = yes (16)
isprint(0x24 aka '$') = yes (16)
isprint(0x25 aka '%') = yes (16)
isprint(0x26 aka '&') = yes (16)
isprint(0x27 aka ''') = yes (16)
isprint(0x28 aka '(') = yes (16)
isprint(0x29 aka ')') = yes (16)
isprint(0x2a aka '*') = yes (16)
isprint(0x2b aka '+') = yes (16)
isprint(0x2c aka ',') = yes (16)
isprint(0x2d aka '-') = yes (16)
isprint(0x2e aka '.') = yes (16)
isprint(0x2f aka '/') = yes (16)
isprint(0x30 aka '0') = yes (4)
isprint(0x31 aka '1') = yes (4)
isprint(0x32 aka '2') = yes (4)
isprint(0x33 aka '3') = yes (4)
isprint(0x34 aka '4') = yes (4)
isprint(0x35 aka '5') = yes (4)
isprint(0x36 aka '6') = yes (4)
isprint(0x37 aka '7') = yes (4)
isprint(0x38 aka '8') = yes (4)
isprint(0x39 aka '9') = yes (4)
isprint(0x3a aka ':') = yes (16)
isprint(0x3b aka ';') = yes (16)
isprint(0x3c aka '<') = yes (16)
isprint(0x3d aka '=') = yes (16)
isprint(0x3e aka '>') = yes (16)
isprint(0x3f aka '?') = yes (16)
isprint(0x40 aka '@') = yes (16)
isprint(0x41 aka 'A') = yes (1)
isprint(0x42 aka 'B') = yes (1)
isprint(0x43 aka 'C') = yes (1)
isprint(0x44 aka 'D') = yes (1)
isprint(0x45 aka 'E') = yes (1)
isprint(0x46 aka 'F') = yes (1)
isprint(0x47 aka 'G') = yes (1)
isprint(0x48 aka 'H') = yes (1)
isprint(0x49 aka 'I') = yes (1)
isprint(0x4a aka 'J') = yes (1)
isprint(0x4b aka 'K') = yes (1)
isprint(0x4c aka 'L') = yes (1)
isprint(0x4d aka 'M') = yes (1)
isprint(0x4e aka 'N') = yes (1)
isprint(0x4f aka 'O') = yes (1)
isprint(0x50 aka 'P') = yes (1)
isprint(0x51 aka 'Q') = yes (1)
isprint(0x52 aka 'R') = yes (1)
isprint(0x53 aka 'S') = yes (1)
isprint(0x54 aka 'T') = yes (1)
isprint(0x55 aka 'U') = yes (1)
isprint(0x56 aka 'V') = yes (1)
isprint(0x57 aka 'W') = yes (1)
isprint(0x58 aka 'X') = yes (1)
isprint(0x59 aka 'Y') = yes (1)
isprint(0x5a aka 'Z') = yes (1)
isprint(0x5b aka '[') = yes (16)
isprint(0x5c aka '\') = yes (16)
isprint(0x5d aka ']') = yes (16)
isprint(0x5e aka '^') = yes (16)
isprint(0x5f aka '_') = yes (16)
isprint(0x60 aka '`') = yes (16)
isprint(0x61 aka 'a') = yes (2)
isprint(0x62 aka 'b') = yes (2)
isprint(0x63 aka 'c') = yes (2)
isprint(0x64 aka 'd') = yes (2)
isprint(0x65 aka 'e') = yes (2)
isprint(0x66 aka 'f') = yes (2)
isprint(0x67 aka 'g') = yes (2)
isprint(0x68 aka 'h') = yes (2)
isprint(0x69 aka 'i') = yes (2)
isprint(0x6a aka 'j') = yes (2)
isprint(0x6b aka 'k') = yes (2)
isprint(0x6c aka 'l') = yes (2)
isprint(0x6d aka 'm') = yes (2)
isprint(0x6e aka 'n') = yes (2)
isprint(0x6f aka 'o') = yes (2)
isprint(0x70 aka 'p') = yes (2)
isprint(0x71 aka 'q') = yes (2)
isprint(0x72 aka 'r') = yes (2)
isprint(0x73 aka 's') = yes (2)
isprint(0x74 aka 't') = yes (2)
isprint(0x75 aka 'u') = yes (2)
isprint(0x76 aka 'v') = yes (2)
isprint(0x77 aka 'w') = yes (2)
isprint(0x78 aka 'x') = yes (2)
isprint(0x79 aka 'y') = yes (2)
isprint(0x7a aka 'z') = yes (2)
isprint(0x7b aka '{') = yes (16)
isprint(0x7c aka '|') = yes (16)
isprint(0x7d aka '}') = yes (16)
isprint(0x7e aka '~') = yes (16)
isprint(0x7f aka '') = no (0)
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?两周前注意到我的应用程序发生了变化.这可能是由某些Windows或Visual Studio更新引起的吗?我检查了两种情况下的线程区域设置是否相同.

Windows 10 build 17134.165

Ian*_*ank 5

@Meinersbur感谢您报告此事.我试图理解差异,因为我只是在我们的构建机器上而不是在我的工作站上看到它.

为了其他人来到这里,微软的回复(见https://developercommunity.visualstudio.com/content/problem/297085/changing-result-of-isspacet.html)是:

isprint()报告为打印字符的选项卡是Universal C Runtime中的回归,它随更新KB4338819一起显示.它将在未来的服务更新中修复,并将在Windows的下一个主要版本中修复.

该问题与/ MD或/ MDd设置无关.使用/ MD构建时,Universal C Runtime将由System32中的OS版本提供,该版本将随操作系统版本而变化.使用/ MDd构建时,您将收到Windows SDK和Visual Studio附带的调试版本,您将使用已安装的最新版本.

如果您希望在所有操作系统上具有与在调试模式下看到的相同的行为,则可以通过使用/ MT构建来静态链接C运行时.

希望这可以帮助!

Steve Wishnousky软件工程师II - Visual C++库