我正在尝试了解我在测试更改时看到的内容。该平台是带有GCC 4.8的openSUSE 42,但它可能会影响其他人。测试代码和错误如下。
$ cat test.cxx
#include <string>
#if (__cplusplus >= 201103L)
# define STATIC_CONSTEXPR static constexpr
# define CONSTEXPR constexpr
#else
# define STATIC_CONSTEXPR static const
# define CONSTEXPR
#endif
struct Name
{
STATIC_CONSTEXPR char* GetName() {return "XXX";}
};
int main(int argc, char* arv[])
{
const char* name = Name::GetName();
return 0;
}
和
$ g++ -O3 -std=c++11 test.cxx -o test.exe
test.cxx: In static member function ‘static constexpr char* Name::GetName()’:
test.cxx:13:44: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
STATIC_CONSTEXPR char* GetName() {return "XXX";}
^
添加以下不会清除它:
struct Name
{
STATIC_CONSTEXPR char* const GetName() {return "XXX";}
};
添加以下确实清除它:
struct Name
{
STATIC_CONSTEXPR const char* GetName() {return "XXX";}
};
根据Does static constexpr variable make sense?:
声明constexpr的每个变量都是隐式const而不是const和 static几乎是正交的(除了与静态的交互 const整数。)
我以为我最了解constexpr
但我显然错过了某些事情(再次)。根据我的理解,C ++委员会认为重现器中的 "XXX"
之类的值可以在文件保存后以某种方式发生变化,即使根据我们目前理解的物理世界规律它是不可能的他们。但是,为了解决这个问题,他们给了我们constexpr
。另一种解释是here,但我必须承认,我没有看到更有效的细节。
为什么我会看到警告,为什么我有效地需要static constepr const
来压制它?
$ uname -a
Linux opensuse-42 4.1.27-27-default #1 SMP PREEMPT Fri Jul 15 12:46:41 UTC 2016 (84ae57e) x86_64 x86_64 x86_64 GNU/Linux
opensuse-42:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.8/lto-wrapper
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr ... --host=x86_64-suse-linux
Thread model: posix
gcc version 4.8.5 (SUSE Linux)
答案 0 :(得分:8)
setValueAtTime
表示函数是var context = new AudioContext();
var gain = context.createGain();
gain.connect(context.destination);
var osc = context.createOscillator();
osc.frequency.value = 300;
osc.connect(gain);
osc.start(context.currentTime + 1);
gain.gain.value = 0;
,而不是它的返回类型。
所以你的问题实际上归结为以下语法错误:
constexpr
从C ++ 11开始,这种从constexpr
到char * foo = "bar";
的转换是非法的,并且自C ++ 98以来已被弃用。
使指针变为const而不是指向const的指针进行了更深入的探讨here。
因此,要返回字符串文字,您需要使用char const[]
。 char*
和char const*
与此问题无关。
答案 1 :(得分:3)
字符串文章"..."
的类型为const char[]
,即const
个字符的数组。如果需要,它可以衰减到const char*
。
您收到警告是因为您使用的是从const char*
到char*
/ char* const
的已弃用转化。函数是constexpr
并不重要,它只适用于函数本身,而不适用于返回值。在返回值上指定constexpr
是没有意义的,因为它或者因为函数而已经是constexpr。
因此,您的代码等同于编写
char* return_value = "XXX";
char* const return_value = "XXX";
因为这些指针都没有指向const char
,所以会收到警告。
答案 2 :(得分:2)
constexpr
与此无关。
char *foo() { return "ABC"; }
会给出同样的警告。 "ABC"
是一个字符串文字,类型为const char[4]
(四个常量字符的数组)。像任何其他数组一样,它很容易衰变为类型为char const *
的指针(指向常量字符的指针)。
对于字符串文字(仅限),还有一个不推荐的转换为char *
(指向非const char的指针) - 这就是你的函数正在使用的,这就是海湾合作委员会不喜欢。修复是:
char const *foo() ...
或(等效地)
const char *foo() ...