为什么有一个定义了_tmain的宏?

7

我是一名新手C++编程人员,之前有Java和C#的背景。我对于以最基本的 #define 开头的术语多如牛毛感到困惑:

#define _tmain wmain

当我很久以前学了一点C语言时,主函数是:

int main(int argc, char *argv[])

在我创建的Visual C++项目中,它生成了主函数:
int _tmain(int argc, _TCHAR* argv[])

我想知道为什么需要将wmain转换成_tmain? 为什么不直接使用原始的C main函数原型?
通常情况下,有很多# define重命名一些看起来很清晰的东西,变成了更加神秘和不清晰的东西(我的意思是wmain变成了_tmain ??)。
感谢您容忍这可能是一个非常明显的问题。

7
这是关于Windows的特定内容,与标准C++(和C)无关。微软有一个糟糕的习惯,即使用可怕的命名方案并不必要地使事情复杂化。 - eq-
2
从前,有人认为使用char来迁移旧版Windows到新版使用wchar_t是一个好主意,但事实并非如此,现在只会让人们感到困惑! - Bo Persson
1
相关:https://dev59.com/i3VC5IYBdhLWcg3woCnN - dan04
2个回答

13
这是一个Visual C++特有的功能,它不是C++的一部分。
大多数Windows API函数都有两个版本:以W结尾的用于宽字符字符串(wchar_t字符串),以及以A结尾的用于窄字符字符串(char字符串)。实际的Windows API“函数”没有后缀,并且被定义为宏,根据设置展开到正确的版本。 T名称(如_TCHAR_tmain)也是为了同样的目的:它们是宏,根据编译设置展开到正确的名称,因此对于宽字符支持,使用wchar_twmain,对于窄字符支持,使用charmain
这样做的想法是,如果您使用字符类型不可知的名称(T名称)编写代码,则可以将代码编译为使用窄字符(ASCII)或宽字符(Unicode)而无需更改。代价是您的代码不太可移植。

@Sam:那要看情况。如果你正在编写大量使用Windows API的代码,使用TCHAR和相关函数可能非常有用。如果你正在编写需要在多个平台上移植的代码,则不应使用TCHAR和相关函数。我在C++中很少涉及Windows特定的编程,所以我可能不是最好的人选。我在C++中参与的所有重要项目都将可移植性作为首要要求。 - James McNellis
2
@Sam:既然你说你是C++编程的新手,我强烈建议你先学习编写可移植的C++代码,并尽可能避免使用语言扩展和特定于平台的功能。只有在必要时(例如,当你必须与操作系统进行交互或使用不可通过C++标准库访问的功能时)才尝试编写特定于平台的代码。当你确实需要使用特定于平台的代码时,请尽可能将其隔离,以便在必要时可以轻松地将代码移植到其他平台。 - James McNellis
1
@James:只有在使用不同的API针对不同的Windows版本时,它才稍微有用。但现在已经没有这种情况了。所以你可以使用wchar_t,这就是TCHAR宏所展开的内容。 - Bo Persson
1
@James:感谢你的书籍推荐。我喜欢这些书籍的推荐。(目前我唯一的一本书是一本旧 Teach Yourself C++ 书籍。)对我来说,关键是尽快将我在 Java(和 C#)中所知道的东西翻译成 C++。我想尽可能消除多余的复杂性。我会采纳建议,从标准 C++ 开始学习,然后在最后学习任何需要的 Windows 特定实践。(我的桌面是 Windows XP,但我们的运行环境是 Linux。) - Sam Goldberg
@James:大多数库没有像Windows API那样对charwchar_t进行过载。 - dan04
显示剩余3条评论

5

由于微软认为将Unicode支持添加到C++的最佳方法是添加一个TCHAR类型,该类型被#定义为charwchar_t,具体取决于项目属性>配置属性>常规>字符集的值。根据该设置,_tmain也被#定义为main(接受char)或wmain(接受wchar_t)。


2
@Sam:不幸的是,Windows操作系统组是C专家,所以他们使用#define而不是typedef,并且使用宏而不是内联函数。这导致成千上万个恶意宏进入了Windows头文件中,当其中一个意外匹配到您的函数名称时,您会注意到这一点。 :-( - Bo Persson
1
另一方面,Unix开发人员决定将Unicode支持添加到C++中的最佳方式是使用UTF-8。 - dan04
1
@BoPersson - ...最值得注意的是max和min宏,它们实际上会破坏STL。 - T.E.D.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接