英文:
How to skip a C++ preprocessor directive in C#
问题
以下是您要翻译的内容:
我试图在C++和C#中使用相同的类。我正在使用预处理器指令来处理代码差异。然而,即使它们位于#if #endif部分中,我也无法跳过C++指令(如#include或#define)。
以下代码在C++中编译,但在C#中不编译:
#if !NET
#pragma once
#include <string> //<-- C# error CS1024: Preprocessor directive expected
#define public public: //<-- C# error CS1025: Single-line comment or end-of-line expected
#endif
#if NET
namespace A.B {
#else
namespace A::B {
using namespace std;
#endif
class C {
string str;
public C() {str = "test";}
};
}
#if !NET
#undef public
#endif
问题:
- 为什么我不能这样做?
- 为什么C#预处理器尝试理解位于#if !NET部分内的#include或#define指令?
- 有没有办法做到这一点?
编辑:
哎呀!重新阅读C#标准规范的第6.5.5章,我注意到以下段落:
> 剩余的条件部分将被跳过,源代码中不会生成任何标记,除了那些用于预处理指令的标记。因此,跳过的源代码,除了预处理指令外,在词法上可能是不正确的。跳过的预处理指令必须在词法上正确,但不会被其他方式处理。在正在跳过的条件部分中,任何嵌套的条件部分(包含在嵌套的#if...#endif结构中)也将被跳过。
- 所以,好的,我的第一个问题得到了答案。
- 第二个问题呢:为什么预处理指令必须在词法上正确?
- 不过,有人知道如何避免这个限制吗?如何使上述代码工作?
英文:
I am trying to use the same class in C++ and C#. I am using preprocessor directives to scape code differences. However, I cannot skip C++ directives (as #include
or #define
) even when they are inside an #if
#endif
section.
The following code compiles in C++, but not in C#:
#if !NET
#pragma once
#include <string> //<-- C# error CS1024: Preprocessor directive expected
#define public public: //<-- C# error CS1025: Single-line comment or end-of-line expected
#endif
#if NET
namespace A.B {
#else
namespace A::B {
using namespace std;
#endif
class C {
string str;
public C() {str = "test";}
};
}
#if !NET
#undef public
#endif
Questions:
- Why can I not do this?
- Why C# preprocessor tries to understand
#include
or#define
directives if they are inside an#if !NET
section? - Is there anyway to do it?
EDIT:
Ouch! Rereading chapter 6.5.5 of the C# standard specification, I notice the following paragraph:
> Any remaining conditional sections are skipped and no tokens, except those for pre-processing directives, are generated from the source code. Therefore skipped source code, except pre-processing directives, may be lexically incorrect. Skipped pre-processing directives shall be lexically correct but are not otherwise processed. Within a conditional section that is being skipped any nested conditional sections (contained in nested #if...#endif
constructs) are also skipped.
- So, ok, my first question is answered.
- What about the second one: Why pre-processing directives shall be lexical correct?
- However, does anybody know how to avoid this limitation? How to make the above code work?
答案1
得分: 0
终于,我找到了一种使用两个文件解决这个问题的方法:
注意: 这可能不是最佳的想法,但我找不到比这更好的方法。
/*** myfile.hpp ***/
#pragma once
#include <string>
#define public public:
#include "myfile.cs"
#undef public
/*** myfile.cs ***/
#if NET
namespace A.B {
#else
namespace A::B {
using string = std::string;
#endif
class C {
string str;
public C() {str = "test";}
};
}
使用这两个文件,C++ 中应该包括myfile.hpp
,而在C#中只需要myfile.cs
。
这个想法来自于这里:https://stackoverflow.com/a/56839291/13087883
英文:
Finally, I have found a method to solve this issue using two files:
Note: It may not be the best idea, but I can't find a better one than this.
/*** myfile.hpp ***/
#pragma once
#include <string>
#define public public:
#include "myfile.cs"
#undef public
/*** myfile.cs ***/
#if NET
namespace A.B {
#else
namespace A::B {
using string = std::string;
#endif
class C {
string str;
public C() {str = "test";}
};
}
With these two files, on C++ myfile.hpp
should be included, and on C# only myfile.cs
is needed.
The idea is taken from here: https://stackoverflow.com/a/56839291/13087883
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论