根据C++'03标准2.3/1:
在进行任何其他处理之前,每个出现的以下三个字符序列之一("三字符序列")被表1中指示的单个字符替换.
Run Code Online (Sandbox Code Playgroud)---------------------------------------------------------------------------- | trigraph | replacement | trigraph | replacement | trigraph | replacement | ---------------------------------------------------------------------------- | ??= | # | ??( | [ | ??< | { | | ??/ | \ | ??) | ] | ??> | } | | ??’ | ˆ | ??! | | | ??- | ˜ | ----------------------------------------------------------------------------
在现实生活中,这意味着代码printf( "What??!\n" );将导致打印,What|因为??!是一个被|字符替换的三字符序列.
我的问题是使用三字母的目的是什么?使用三字母有什么实际优势吗?
UPD:在答案中提到一些欧洲键盘没有所有标点字符,所以非美国程序员必须在日常生活中使用三字母组合?
UPD2:Visual Studio 2010默认情况下关闭了三字母支持.
有没有人引用海报/单页pdf或类似的东西与C语言的八个翻译阶段列表(第一个是三字母翻译)?我想在我的电脑旁边的墙上挂一个印刷品.
更新:抱歉忘记指定.我对C90很感兴趣(虽然C99可能非常接近,_Pragma如pmg所说,答案是C99特定的,我想避免这种情况).
我破解了以下代码:
unsigned long long get_cc_time () volatile {
uint64 ret;
__asm__ __volatile__("rdtsc" : "=A" (ret) : :);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
它适用于 g++,但不适用于 Visual Studio。我怎样才能移植它?检测 VS/g++ 的正确宏是什么?
在一些 doxygen 文档中,我想显示 a 的内容#define,而不是标签本身。例如,在一个 C 文件中我有
#define REPEAT_N_TIMES 10
Run Code Online (Sandbox Code Playgroud)
现在我想在我的文档中显示:
该动作进行10次。
如果我使用\ref REPEAT_N_TIMES,它会显示:
该操作已执行 REPEAT_N_TIMES 次
有没有办法显示链接的内容,而不是链接本身,例如像\ValueOf(\ref REPEAT_N_TIMES)或\contentOf(\ref REPEAT_N_TIMES)?
更新:我的 Doxygen 的配置是:
// Configuration options related to the preprocessor
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = WXUNUSED()=
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
Run Code Online (Sandbox Code Playgroud)
该MACRO_EXPANSION设置似乎改变了宏的“细节”。但我没有找到选择宏名称或其内容的方法。使用该命令\ref似乎不是正确的方式:它指的是“某物”而不是“某物”的内容
是否有我可以使用的运算符或函数,可能类似于C,我可以在其中使用类似的东西\ref *something而不是\ref something?
我的代码中包含一些日志记录宏,内容如下:
#define LOG_MSG (pri, msg, ... ) \
if (pri > PriorityLevel ) \
printf( msg, ##\__VA_ARGS__);
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用LCOV_EXCL_START,LCOV_EXCL_STOP或LCOV_EXCL_LINE来禁止分支。但这仅在我将其调用LOG_MSG的每个位置添加时才起作用:
LOG_MSG(ERROR, "An Error has occurred\n");//LCOV_EXCL_LINE
我想在宏中包含该注释,但是如果我将其放在其中,LCOV将无法识别它。例如,此代码仍会产生分支。
#define LOG_MSG (pri, msg, ... ) \
if (pri > PriorityLevel ) \
printf( msg, ##\__VA_ARGS__);//LCOV_EXCL_LINE
Run Code Online (Sandbox Code Playgroud)
有没有一种好的方法可以抑制宏本身中的这些分支?
C预处理器(cpp)似乎应该正确处理此代码:
#define A 1 // hello there
int foo[A];
Run Code Online (Sandbox Code Playgroud)
我希望A能用1.
发生的事情是A替换为1 // hello there,从而产生以下输出cpp -std=c99 test.c:
# 1 "test.c"
int foo[1 // hello there];
Run Code Online (Sandbox Code Playgroud)
哪个是无效的C并且无法编译.
我怎样才能cpp进行正确的更换?
关于编译器的注意事项:使用cppmac上最新的(8.2.1,2016年12月)Xcode,所以我怀疑它是由于过时的编译器.
为什么会出现以下错误?
#include <iostream>
#define concatenate(t1, t2) t1 ## t2 // Concatenate token1 and token2
int main()
{
int myVar = 22;
std::cout << concatenate(my, Var); // Compiles fine and outputs the value of myVar
concatenate(/, /) So I thought that this would be a comment but this is a compile-time error
// error: pasting "/" and "/" does not give a valid preprocessing token
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我认为这concatenate(/, /)会告诉预处理器用 a 替换它,//然后当它进一步解析时,整行将被解释为注释。
在这种情况下实际发生了什么?
以下行写在C程序中
in/*hello*/t k; error or not
Run Code Online (Sandbox Code Playgroud)
据我说,第一个预处理器会从代码中删除注释,然后代码将转到编译器,因此编译器的代码是
int k;
Run Code Online (Sandbox Code Playgroud)
这完全没问题.
但实际上,当我在gcc编译器上运行它时,它会给出编译器错误
in,k,t没有定义