快速提问:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
Run Code Online (Sandbox Code Playgroud)
这两个功能在每个方面都是相同的还是有区别的?我对C语言的答案感兴趣,但如果C++语言中有一些有趣的东西,我也想知道.
在许多程序中,a #define用作与常量相同的目的.例如.
#define FIELD_WIDTH 10
const int fieldWidth = 10;
Run Code Online (Sandbox Code Playgroud)
我通常认为第一种形式优先于另一种,依靠预处理器来处理基本上是应用程序的决定.这个传统有原因吗?
在C中,我是否更喜欢常量而不是定义?我最近阅读了很多代码,所有的例子都大量使用了定义.
这曾经在几周前工作:
template <typename T, T t>
T tfunc()
{
return t + 10;
}
template <typename T>
constexpr T func(T t)
{
return tfunc<T, t>();
}
int main()
{
std::cout << func(10) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但现在g++ -std=c++0x说:
main.cpp: In function ‘constexpr T func(T) [with T = int]’:
main.cpp:29:25: instantiated from here
main.cpp:24:24: error: no matching function for call to ‘tfunc()’
main.cpp:24:24: note: candidate is:
main.cpp:16:14: note: template<class T, T t> T tfunc()
main.cpp:25:1: warning: control reaches …Run Code Online (Sandbox Code Playgroud) 虽然这编译:
char* p2c;
const char* p2cc = p2c; //fine
Run Code Online (Sandbox Code Playgroud)
因为lhs指向类型具有rhs指向类型的所有限定符,所以不会:
char** p2p2c;
const char** p2p2cc = p2p2c; //fail
Run Code Online (Sandbox Code Playgroud)
但这样做:
const char * const * p2cp2cc = p2p2c; //fine
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?
我被告知如果我在ANSI-C中编码以按照将要使用的变量的顺序声明,断言指针不是null并且索引在边界内,并且在使用变量之前初始化.
如果我声明一个const,我可以在一个断言和代码块之后初始化它吗?在Java中,最终初始化必须在声明时进行,但是通过ANSI-C实现它是否一致,我可以初始化const一次但不一定在声明时?
有人问我怎样才能改变const变量的值.
我明显的回答是"指针!" 但我尝试了下一段代码,我很困惑......
int main()
{
const int x = 5;
int *ptr = (int *)(&x); // "Cast away" the const-ness..
cout << "Value at " << ptr << ":"<< (*ptr) <<endl;
*ptr = 6;
cout << "Now the value of "<< ptr << " is: " << (*ptr) <<endl;
cout << "But the value of x is still " << x <<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Value at <some address> :5
Now the value of <same address> is: 6 …Run Code Online (Sandbox Code Playgroud) 以execve(2)为例,根据posix有这个原型[1]:
int execve(const char *path, char *const argv[], char *const envp[]);
Run Code Online (Sandbox Code Playgroud)
对我来说,似乎好像
int execve(const char *path, const char *const argv[], const char *const envp[]);
Run Code Online (Sandbox Code Playgroud)
本来是一个明显的改进.
所以,有谁知道为什么会这样?什么可以解释是否需要可能操纵给定的argv/envp字符串?
[1] http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html
在解释和创建函数参数的类型时,我很难理解为什么C++比C更"放松"的行为.
C做世界上最简单的事情,它坚持你写的东西就是这样,另一方面,C++以一种我无法理解的扭曲方式运作.
例如,流行的argv是一个char* []传递给函数的时候变成了char**,我真的不明白为什么,我期待和"想要" char * const *但是我得到了这种行为.
您还可以阅读PDF中讨论C和C++之间差异的文章,文章也以这句话结尾:
虽然C++在确定函数签名时会忽略参数声明中的顶级cv限定符,但它并不完全忽略这些cv限定符.
因为我在网上找不到这个问题(嵌入式系统编程 - 2000年2月,这个老问题是免费的),我想知道这句话可能意味着什么.
有人可以解释为什么这种行为是它在C++中的行为?
编辑:
我的一个例子是
#include <stdio.h>
void foo(int argc, const char *const *const argv) {
printf("%d %s\n", argc, argv[0]);
}
int main(int argc, char *argv[]) {
foo(argc, argv);
return (0);
}
Run Code Online (Sandbox Code Playgroud)
如果你编译它,gcc 4.8.1你得到预期的错误
gcc cv_1.c
cv_1.c: In function ‘main’:
cv_1.c:8:3: warning: passing argument 2 of ‘foo’ from incompatible pointer type [enabled by default]
foo(argc, argv);
^
cv_1.c:3:6: …Run Code Online (Sandbox Code Playgroud)