我正在尝试在 Fortran 中模拟 C 断言,以便强制执行所有过程的前置条件和后置条件。通过这种方式,我可以向用户提供有关运行时错误的更详细的信息,而不是我可以合理预期维护的信息。
为了实现这一点,我使用了预处理器指令__FILE__和__LINE__,并定义了一个assert扩展为 Fortran 子例程调用的宏。我没有尝试在这里描述它,而是创建了一个git 存储库,其中包含一些示例代码。如果你用它来构建它
make test
./test
Run Code Online (Sandbox Code Playgroud)
该函数挂起,因为您调用的函数需要正参数和负参数。但是,如果您使用
make test DEBUG=1
./test
Run Code Online (Sandbox Code Playgroud)
错误被断言捕获。
这适用于 gfortran 和 Intel Fortran 编译器。我无法访问其他 Fortran 编译器。如果文件扩展名是 ,我可以合理地期望其他编译器进行必要的源预处理吗.F90?或者我应该依靠旗帜-cpp?最便携的方法是什么?我到底应该这样做吗?
我想要一种具有“全局预处理器定义”的方法,以便我可以在编译之前更改单个值以添加或删除程序的功能。目前我有一个“全局脚本”(称为 God.cs),其常量如下:
public const bool PRINT_RUN_VALUES = true;
public const bool DEBUG_MOVEMENT = false;
public const bool DOUBLE_SPEED = false;
Run Code Online (Sandbox Code Playgroud)
所有相关脚本都使用这些值,例如:
在脚本1中:
if (God.PRINT_RUN_VALUES) {
float averageDist = /* calculate values */
print("Script1: averageDist = " + averageDist);
}
Run Code Online (Sandbox Code Playgroud)
在脚本2中:
if (God.PRINT_RUN_VALUES) {
print("Script2: radius = " + radius);
print("Script2: time = " + time);
}
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是我得到了很多
CS0162:检测到无法访问的代码
警告。我可以使用以下方法关闭这些警告:
#pragma warning disable 0162
#pragma warning disable 0429
Run Code Online (Sandbox Code Playgroud)
但我不想这样做,因为这些警告在不涉及 God.cs 中的这些值的情况下可能很有用。另一种方法可能是使用经典的预处理器定义,例如:
#define PRINT_RUN_VALUES
...
#if (PRINT_RUN_VALUES)
float averageDist = /* calculate …Run Code Online (Sandbox Code Playgroud) 在 Windows 上使用 clang 编译器会抛出“预处理器表达式启动时的无效标记”
#if __WORDSIZE == 64
Run Code Online (Sandbox Code Playgroud)
./bits/types.h:42:16:错误:预处理器表达式开头的标记无效
为了确保 __WORDSIZE 已定义,我添加了
#define __WORDSIZE
Run Code Online (Sandbox Code Playgroud)
./bits/wordsize.h:8:9: warning: '__WORDSIZE' macro redefined [-Wmacro-redefined]这会按预期发出警告
我已经做了一些谷歌搜索,但没有发现任何关于预处理器指令嵌套的正面陈述。我希望能够做这样的事情:
#if FOO
// do something
#if BAR
// do something when both FOO and BAR are defined
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
我知道我可以做类似下面的事情,但只是想知道。
#if FOO && (!BAR)
#elif FOO && BAR
#endif
Run Code Online (Sandbox Code Playgroud)
(编辑)实际上,我的代码中已经有一个更复杂的嵌套语句,但它没有按照我的预期执行。因此,我很好奇是否有官方对此的看法。
我的代码:
#include <stdio.h>
#define PRODUCT(x) (x * x)
int main()
{
int i = 3, j, k, l;
j = PRODUCT(i + 1);
k = PRODUCT(i++);
l = PRODUCT(++i);
printf("%d %d %d %d", i, j, k, l);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么输出是:
7 7 12 49.
Run Code Online (Sandbox Code Playgroud)
宏中是否有任何错误或其他问题?
是否有一个虚拟缩放器可以插入不执行任何操作的管道中?IE
# define the SVM model using the RBF kernel
model = Pipeline(steps=[('preprocess', MinMaxScaler()),
('model', SVC(kernel='rbf',
gamma='scale',
probability=True,
class_weight='balanced',
cache_size=1000,
tol=1e-10,
shrinking=True,
decision_function_shape='ovr',
break_ties=False,
C=3.0))])
params = [{'preprocess': [DummyDoNothingScaler(), MaxAbsScaler(), MinMaxScaler(), StandardScaler()],
'model__gamma': ['scale', 'auto'],
'model__C': [1.0, 1.01, 1.015,3.0]
}]
Run Code Online (Sandbox Code Playgroud)
有没有DummyDoNothingScaler?
像 cpp 和 fpp 这样的常见预处理器是否会扩展由一对引号括起来的宏?
我同时使用 cpp 和 fpp 尝试了以下代码,似乎引号内的宏没有展开。但是,我在有关 cpp 或 fpp 的任何文档中都没有找到此规则。任何人都可以指导我查看一些文档,以便我可以确定这种行为吗?谢谢。
#define X Y
X
"X"
'X'
Run Code Online (Sandbox Code Playgroud) 我有这行代码:
#define ALPHABET_SIZE 'z' - 'a' + 1
Run Code Online (Sandbox Code Playgroud)
当我将鼠标悬停在代码中的任意位置 ALPHABET_SIZE 上时,它告诉我它扩展到'z' - 'a' + 1. 所以我想知道每次在我的代码中使用 ALPHABET_SIZE 时是否必须重新计算这个表达式?如果是这样,我怎样才能防止重新计算?
我们有一些旧的 C++ 代码,其中包含只有在__gnu_linux__定义预处理器符号时才编译的部分。在我的 Ubuntu 20.04 和 GCC 9.3 上编译不是问题。现在,我们尝试将其移植到基于 Alpine Linux 和 GCC 10.2 的 Docker 容器,并发现在__gnu_linux__这种情况下未定义。
因此,我搜索了有关__gnu_linux__预处理器宏的任何文档,但在 GCC 或其预处理器 CPP 的文档中找不到任何内容。我能找到的唯一提示是以下预定义符号列表,但它没有提到任何文档:https : //sourceforge.net/p/predef/wiki/OperatingSystems/
__gnu_linux__预处理器宏的任何官方文档?通过在 中进行全文搜索,/usr我获得了一些点击。一个是 Boost 头文件也查询该宏,另外两个是二进制文件cc1和cc1plus. 我发现那些是分别为 C 和 C++ 实现预处理器的 GCC 的内部工具,但我找不到这些的任何官方文档。所以,我克隆了 GCC 源代码库,发现它__gnu_linux__在更改日志中只提到了一次,并且包含一些特殊的提交,用 更改了一行__gnu_linux__,但没有一个对它做出明确的声明。
假设我想确保始终使用不同的参数值(编译时)调用该函数。
理想的情况是这样可以编译:
enum en {
en_A,
en_B
};
...
foo(en_A);
Run Code Online (Sandbox Code Playgroud)
但这失败了:
enum en {
en_A,
en_B
};
...
foo(en_A);
...
foo(en_A);
Run Code Online (Sandbox Code Playgroud)
因此,我们应该只能调用某个函数 foo(en_A) 一次(对于 foo(en_B) 也是如此)。
不太可取但也可以接受的方法是定义 foo_en_A、foo_en_B 并确保它们每个仅被调用一次。
在 C 语言中是否可以做类似编译时的事情?
preprocessor ×10
c ×4
c# ×2
fortran ×2
macros ×2
c++ ×1
clang ×1
compile-time ×1
definition ×1
gcc ×1
global ×1
gnu ×1
linux ×1
output ×1
python ×1
scikit-learn ×1
unix ×1