根据c ++标准,以下程序是否格式良好或格式不正确?
namespace X { int i; }
namespace Y { using X::i; }
int main() { using X::i; using Y::i; }
Run Code Online (Sandbox Code Playgroud)
我用不同的编译器得到了不同的结果:
我不想修复这个程序让它在GCC上编译.我只是想知道c ++标准对此有何看法以及为什么三个编译器的行为不同.此外,我想如果这是任何这些编译器中的错误的结果.
考虑以下程序.根据c ++标准(参考所需标准的相关部分)是否格式良好:
namespace X { extern int i; }
namespace N { using X::i; }
int N::i = 1;
int main() {}
Run Code Online (Sandbox Code Playgroud)
我为不同的编译器得到了不同的结果.我正在试图弄清楚我应该为哪个编译器提交错误报告:
Clang:给出以下编译器错误:名称空间'N'中没有名为'i'的成员
GCC和Visual C++编译它没有错误.
为了比较,下面给出了所有三个编译器的编译器错误:
namespace X { void f(); }
namespace N { using X::f; }
void N::f() {};
int main() {}
Run Code Online (Sandbox Code Playgroud) 以下程序与MSVS,clang和GCC编译时没有错误:
class A;
namespace Y {
using ::A;
class A {};
}
int main() {}
Run Code Online (Sandbox Code Playgroud)
现在让我们定义一个成员函数.现在它仍然可以编译MSVS和clang,但不能与GCC编译:
class A;
namespace Y {
using ::A;
class A { void f() {} };
}
int main() {}
Run Code Online (Sandbox Code Playgroud)
GCC给出以下错误消息:
这是为什么?这是GCC中的错误吗?
如果该程序的第二个版本违反了c ++标准的规则,它违反了什么规则,为什么MSVS和clang没有为该违规提供诊断消息?
这是c ++标准含糊不清的情况吗?
从错误消息看起来GCC错误地认为我们违反了以下规则:
我们没有违反此规则,因为成员函数定义在类定义中.我的理论是,海湾合作委员会混淆了宣言类A; 在全局命名空间中,在命名空间Y中有类定义类A {...}.我认为我们在GCC中有一个错误.
通过海湾合作委员会,他们宣布同一实体.通过观察在程序的第一个版本中可以看出,在使用GCC进行编译时,可以使用:: A作为main中的完整类型.MSVS也是如此.然而,对于Clang,他们宣布了不同的实体.这种差异可能是因为c ++标准的模糊性.无论这种模棱两可,我们显然都没有违反http://eel.is/c++draft/class.mfct#2.这个规则很清楚.
在下面的示例代码中,我在执行以下操作时遇到以下异常db.Entry(a).Collection(x => x.S).IsModified = true:
System.InvalidOperationException: '无法跟踪实体类型 'B' 的实例,因为另一个具有键值 '{Id: 0}' 的实例已被跟踪。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。
为什么不添加而不是附加 B 的实例?
奇怪的是,文档IsModified没有指定InvalidOperationException为可能的例外。无效的文档或错误?
我知道这段代码很奇怪,但我写它只是为了了解 ef core 在一些奇怪的 egde 情况下是如何工作的。我想要的是解释,而不是解决方法。
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public class A
{
public int Id { get; set; }
public ICollection<B> S { get; set; } = new List<B>() { new B {}, new B {} };
}
public class B
{
public int Id { get; …Run Code Online (Sandbox Code Playgroud) 考虑以下程序:
#include <iostream>
namespace N {
int j = 1;
}
namespace M {
typedef int N;
void f() {
std::cout << N::j << std::endl;
}
}
int main() { M::f(); }
Run Code Online (Sandbox Code Playgroud)
使用clang编译它会产生以下编译器错误:
prog.cc:10:22: error: 'N' (aka 'int') is not a class, namespace, or
enumeration
std::cout << N::j << std::endl;
^ 1 error generated.
Run Code Online (Sandbox Code Playgroud)
GCC不会给出任何编译器错误.我正在试图弄清楚我应该为什么编译错误报告.哪个编译器具有正确的行为和原因(引用c ++标准)?
Wandbox - Clang:http://melpon.org/wandbox/permlink/s0hKOxCFPgq5aSmJ
Wandbox - GCC:http://melpon.org/wandbox/permlink/i2kOl3qTBVUcJVbZ
在gcc中使用-pedantic-errors和-Werror = pedantic有什么区别?
根据海湾合作委员会的文件,有一点不同:
-pedantic-错误
只要基本标准(请参阅-Wpedantic)需要诊断,在某些情况下在编译时存在未定义的行为,并且在某些其他情况下不会阻止根据标准编译有效的程序,则会发出错误.这不等同于-Werror = pedantic,因为此选项启用了错误而后者未启用,反之亦然.
-pedantic-errors包含哪些错误,但不包括-Werror = pedantic?
-Werror = pedantic包含哪些错误,但不包括-pedantic-errors?
这两种错误的任何一个例子?
考虑以下 Rust 程序:
fn main()
{
let mut x = 1;
let mut r = &x;
r;
let y = 1;
r = &y;
x = 2;
r;
}
Run Code Online (Sandbox Code Playgroud)
它编译时没有任何错误,我同意这种行为。
问题是,在尝试正式对此进行推理时,我无法得出相同的结论:
r是&'a i32对某些寿命'a。&x是&'b i32一些生命周期'b。'a包括x = 2;.let mut r = &x;我们知道'b: 'a。'b包括x = 2;。x = 2;借边做的x …从C++ 11标准,§7.3.3[namespace.udecl]/1:
using声明在声明区域中引入了一个名称,其中出现using声明.
使用声明:
using typenameopt nested-name-specifier unqualified-id;
using ::unqualified-id;using声明中指定的成员名称在using声明出现的声明区域中声明.
在使用声明发生的声明性区域中声明的名称是什么意思?
这是否意味着将该名称引入发生using声明的声明性区域?
声明名称和声明名称所代表的实体之间是否有区别?
例:
namespace N { static int i = 1; } /* Declares an entity denoted by
the name i in the declarative region of the namespace N.
Introduces the name into the declarative region of the namespace N.
Declares the name i in the declarative region of the namespace N? */
using N::i; /* Declares the name i in the declarative …Run Code Online (Sandbox Code Playgroud) 根据c ++标准,以下程序是否格式良好或格式不正确?
namespace N { int i; }
using namespace N;
using ::i;
int main() {}
Run Code Online (Sandbox Code Playgroud)
我用不同的编译器得到不同的结果:
根据c ++标准,该程序是否格式良好或格式不正确?需要参考c ++标准.
我正在试图找出应该提交错误的编译器.
c++ using-directives using-declaration language-lawyer name-lookup
考虑以下 Rust 程序:
fn f<'a>(x: &'a i32) {
unimplemented!();
}
fn main() {
f::<'static>;
}
Run Code Online (Sandbox Code Playgroud)
编译时,输出如下编译错误:
fn f<'a>(x: &'a i32) {
unimplemented!();
}
fn main() {
f::<'static>;
}
Run Code Online (Sandbox Code Playgroud)
让我们像这样修改程序:
fn f<'a, 'b>(x: &'a i32) -> &'b i32 {
unimplemented!();
}
fn main() {
f::<'static>;
}
Run Code Online (Sandbox Code Playgroud)
由于某些奇怪的原因,现在编译时没有任何编译错误。为什么是这样?如果第一个程序中的生命周期参数 'a 是后期绑定的,为什么它不应该在第二个程序中也后期绑定?请注意,我在第一个和第二个程序之间所做的唯一更改是添加另一个生命周期参数和一个依赖于这个新生命周期参数的返回类型。
c++ ×6
declaration ×2
gcc ×2
name-lookup ×2
namespaces ×2
rust ×2
c# ×1
definition ×1
entity ×1
lifetime ×1
typedef ×1