相关疑难解决方法(0)

gcc和Microsoft预处理器之间的区别

我发现Microsoft Visual Studio编译器和gcc以不同的方式预处理以下小片段:

# define M3(x, y, z) x + y + z
# define M2(x, y) M3(x, y)
# define P(x, y) {x, y}
# define M(x, y) M2(x, P(x, y))
M(a, b)
Run Code Online (Sandbox Code Playgroud)

'gcc -E'给出以下内容:

a + {a + b}
Run Code Online (Sandbox Code Playgroud)

,'cl/E'发出关于缺少宏参数的警告并产生以下输出:

a + {a, b} +
Run Code Online (Sandbox Code Playgroud)

似乎来自嵌套宏扩展的逗号不被视为参数分隔符.不幸的是,我没有找到cl预处理器中实现的算法的描述,所以我不确定我的建议是否正确.有谁知道cl预处理器是如何工作的,它的算法和gcc之间有什么区别?以及如何解释观察到的行为?

c gcc visual-studio c-preprocessor

17
推荐指数
2
解决办法
2013
查看次数

在没有括号的宏中使用逗号:如何与模板混合和匹配?

考虑一个简单的宏:

#define ECHO(x) x

ECHO(foo(1, 2))
Run Code Online (Sandbox Code Playgroud)

这会产生我们期望的确切输出:

foo(1, 2)
Run Code Online (Sandbox Code Playgroud)

上面的示例有效,因为预处理器可以识别与函数调用相邻的括号.

现在考虑如果我使用模板而不是函数调用会发生什么:

ECHO(template<int, bool>)
Run Code Online (Sandbox Code Playgroud)

这会导致错误,因为预处理器会将宏template<intbool>作为两个单独的参数解释为宏.预处理器无法识别<>范围!

无论如何在宏中使用这样的模板?

c++ macros

8
推荐指数
2
解决办法
6163
查看次数

将需要逗号的模板传递给单参数宏

我有一些代码基本上可以浓缩为

#define FOO(a)
FOO(std::map<int, int>);
Run Code Online (Sandbox Code Playgroud)

但它会发出编译错误(宏的实际参数太多FOO)。

显然,预处理器认为我已经提供了std::map<intint>作为参数。

有没有办法解决这个问题?预处理器不会以这种方式处理带逗号的带引号的字符串。

c++ c-preprocessor

6
推荐指数
1
解决办法
1084
查看次数

typedef和显式实例化之间的代码重复

tree.h中

template<typename Functor, char Operator>
class binary_operation : public node
{
// ... unimportant details ...

    unsigned evaluate() const;
    void print(std::ostream& os) const;
};

typedef binary_operation<std::plus<unsigned>, '+'> addition;
typedef binary_operation<std::multiplies<unsigned>, '*'> multiplication;
// ...
Run Code Online (Sandbox Code Playgroud)

tree.cpp

template<typename Functor, char Operator>
unsigned binary_operation<Functor, Operator>::evaluate() const
{
    // ... unimportant details ...
}

template<typename Functor, char Operator>
void binary_operation<Functor, Operator>::print(std::ostream& os) const
{
    // ... unimportant details ...
}

template class binary_operation<std::plus<unsigned>, '+'>;
template class binary_operation<std::multiplies<unsigned>, '*'>;
// ...
Run Code Online (Sandbox Code Playgroud)

如您所见,头文件中的typedef与实现文件中的显式类模板实例之间存在一些代码重复.有没有办法摆脱不需要像往常一样在头文件中放置"所有"的重复?

c++ templates typedef code-duplication header-files

5
推荐指数
1
解决办法
1250
查看次数

C++预处理器不知道模板参数?

如图所示,如果将具有多个参数的模板实例化作为参数传递给宏,则C++预处理器将失败.

请参阅下面的示例.

#include <stdio.h>

#define FOO(v) printf("%d\n",v::val())

template<int N>
struct bar {
    static int val() { return N; }
};
template<int N, int M>
struct baz {
    static int val() { return N+M; }
};

int main() {
    printf("%d\n",bar<1>::val());
    printf("%d\n",baz<1,2>::val());
    FOO(bar<10>);       // OK
    FOO(baz<20,30>);    // error: too many arguments provided to function-like macro invocation
    FOO((baz<20,30>));  // error: '::val' has not been declared
}
Run Code Online (Sandbox Code Playgroud)

用clang ++和g ++ 测试

它应该被视为一个错误吗?

c++ parameters templates arguments c-preprocessor

5
推荐指数
2
解决办法
557
查看次数

如何在Objective-C中安全地将`_Nullable`强制转换为`_Nonnull`?

在编译时-Wnullable-to-nonnull-conversion,我们会使用以下代码获得正确的警告:

NSString * _Nullable maybeFoo = @"foo";
^(NSString * _Nonnull bar) {  
}(maybeFoo);

Tests.m:32:7: error: implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull' [-Werror,-Wnullable-to-nonnull-conversion]
    }(maybeFoo);
      ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

我如何安全地foo从一个演员阵容NSString * _Nullable到一个NSString * _Nonnull

到目前为止我有最好的解决方案

我想出的最好的就是这个宏:

#define ForceUnwrap(type, nullableExpression) ^type _Nonnull () { \
  type _Nullable maybeValue___ = nullableExpression; \
  if (maybeValue___) { \
    return (type _Nonnull) maybeValue___; \
  } else { \
    NSLog(@"Attempted to …
Run Code Online (Sandbox Code Playgroud)

xcode nullable objective-c ios objective-c-nullability

5
推荐指数
1
解决办法
3589
查看次数

C 预处理器:迭代地将宏扩展为逗号分隔的列表

在后C 预处理器递归宏中使用 Paul Fultz II 的解决方案,我想扩展无限数量的括号宏参数,例如

#define MY_CHAIN (alpha) (beta) (gamma)
Run Code Online (Sandbox Code Playgroud)

到一个逗号分隔的列表中,该列表可以传递给可变参数宏,例如

CHAIN_COMMA(MY_CHAIN) // alpha, beta, gamma
Run Code Online (Sandbox Code Playgroud)

在下面的示例中[alpha] [beta] [gamma],我可以扩展为大括号并使用我尝试过的所有内容分隔列表,但逗号除外alpha :: beta :: gamma

这是我的完整(编译)代码:

#include <iostream>
using namespace std;

// unrelated macro utilities
#define SEE(expression) cout << #expression ": " << STR(expression) << endl;
#define CMD(function, ...) function(__VA_ARGS__)
#define STR(s) CMD(STR_, s)
#define STR_(s) #s

// concatenation
#define CAT(x, y) CAT_(x, y)
#define CAT_(x,y) x ## y // error from CHAIN_COMMA: passed 4 …
Run Code Online (Sandbox Code Playgroud)

comma-operator c-preprocessor variadic-macros

5
推荐指数
1
解决办法
1200
查看次数

C++宏问题(逗号的解释)

以下代码编译正常.

#define CMD_MACRO(pp, cmd)  \
{           \
      if (pp)\
      { cmd; }        \
}

template<class T> void operate_on(T &data, char c) {
  data=data+1;
};

int main() {
  int book=4;
  char c;
    CMD_MACRO(book, {
        operate_on<int>(book, c);
    });
};
Run Code Online (Sandbox Code Playgroud)

请注意,我的代码中的实际宏更复杂,我给出了一个简化版本,这可能没有太大的逻辑意义

现在,如果我在函数中添加另一个模板参数,它会给出编译错误(代码注释中解释的问题):

template<class T, bool b> void operate_on(T &data, char c) {
  data=data+1;
};
int main() {
      int book=4;
      char c;
        CMD_MACRO(book, {
            operate_on<int, false>(book, c); /* here the "," between int and 
                  false is being treated 
                  as separating arguments to CMD_MACRO, 
                  instead …
Run Code Online (Sandbox Code Playgroud)

c++ syntax macros

2
推荐指数
1
解决办法
2227
查看次数

宏htonl将内部逗号解释为参数分隔符

这是在编译时返回的异常错误,仅限于一些编译器参数.

好的 g++ -std=c++11 -m64 -O3 -DNDEBUG

但是g++ -std=c++11 -m64 -Wall -g,出现此问题:

宏"htonl"传递了7个参数,但只占用了1个

码:

const unsigned int h = htonl(hash::CompileTime<'A', 'S', 't', 'r', 'i', 'n', 'g'>::hash);
Run Code Online (Sandbox Code Playgroud)

我不确定问题是来自调用htonl还是来自我的模板化的哈希.

你知道怎么解决这个问题吗?

其他信息:

template<const char C0,         const char C1 =  '\0', const char C2 =  '\0', 
         const char C3  = '\0', const char C4 =  '\0', const char C5 =  '\0', 
         const char C6  = '\0', const char C7 =  '\0', const char C8 =  '\0', 
         const char C9  = …
Run Code Online (Sandbox Code Playgroud)

c++ gcc htonl c++11

2
推荐指数
1
解决办法
39
查看次数

typedef持续多长时间?

我在一个函数中有一个宏来实例化给定类型的变量(并做一些其他不相关的事情).

基本上MACRO(foo, f)扩展到foo f;

但是如果foo说是a std::map<int, int>那么由于额外的逗号,扩展失败了.

我通过写作typedef std::map<int, int> bar;然后解决这个问题MACRO(bar, b).

我很担心,我正在泄漏typedef程序源,这可能会在将来引起我的问​​题.

那么,typedefs持续多久了?

c++

1
推荐指数
1
解决办法
80
查看次数