标签: language-specifications

在while循环中,最后一个逗号分隔语句是否保证最后运行?

考虑以下(普通)代码段:

while (i++, i <= 10) {
  // some more code
}
Run Code Online (Sandbox Code Playgroud)

在一般情况下,C++允许以任何顺序计算逗号分隔的语句.在while循环的情况下,我们是否至少保证(通过规范)最后一个语句(用作循环的条件)?

c++ specifications language-specifications

12
推荐指数
3
解决办法
3847
查看次数

运算符'=='无法应用于类型T?

我认为这种方法有效,但我错了:

static void Equals<T>(T x, T y)
{
    return x == y;    //operator == can't be applied to type T
}
Run Code Online (Sandbox Code Playgroud)

在阅读了规范(v3.0中的第7.2.4节和v4.0中的第7.3.4节)之后:

7.2.4二元运算符重载决策

形式为x op y的操作,其中op是可重载的二元运算符,x是类型X的表达式,y是类型Y的表达式,按如下方式处理:

  • 由X和Y为操作运算符op(x,y)提供的候选用户定义运算符集合被确定.该集合由X提供的候选运算符和Y提供的候选运算符组合而成,每个运算符使用§7.2.5的规则确定.如果X和Y是相同类型,或者如果X和Y是从公共基类型派生的,则共享候选运算符仅出现在组合集中一次.

  • 如果候选用户定义的运算符集合不为空,则这将成为该操作的候选运算符集.否则,预定义的二元运算符op实现(包括它们的提升形式)将成为该操作的候选运算符集.给定运算符的预定义实现在运算符的描述中指定(第7.7节到第7.11节).

  • §7.4.3的重载决策规则应用于候选运算符集合,以根据参数列表(x,y)选择最佳运算符,并且此运算符成为重载解析过程的结果.如果重载解析无法选择单个最佳运算符,则会发生编译时错误.

在第2步中,我认为应该应用此预定义实现:

bool operator ==(object x, object y);
bool operator !=(object x, object y);
Run Code Online (Sandbox Code Playgroud)

因为C#中的所有内容都来自Object.如何在步骤3中发生编译时错误?在这种情况下,我不认为"重载决议无法选择".

编辑当我实现这样的事情时,我想到了这个问题:

class EnumComparer<TEnum> : IEqualityComparer<TEnum>
{
    public bool Equals(TEnum x, TEnum y)
    {
        return x == y;
    }
    public int GetHashCode(TEnum obj)
    {
        return (int)obj;
    }
}
Run Code Online (Sandbox Code Playgroud)

我担心我需要构建一个表达式并在Equals方法中动态调用它.

.net c# operator-overloading language-specifications

12
推荐指数
2
解决办法
2564
查看次数

从Object转换为布尔有效的Java语言?

我在多年前由C程序员实现的工作中偶然发现了一个旧的Java代码,我们不禁开始讨论代码 - 即使它编译和工作 - 实际上是有效的Java代码.

final Object o = Boolean.TRUE;
boolean b = (boolean) o;
Run Code Online (Sandbox Code Playgroud)

这基本上是有问题的代码.正如你所看到的,从对象到原始布尔值有一个不太好的演员,这应该是不可能的,但是由于一些隐含的拳击魔术而恰好起作用.

如果我做以下事情

final Object o = Boolean.TRUE;
if (o instanceof Boolean) {
  b = (boolean) o;
}
Run Code Online (Sandbox Code Playgroud)

我甚至在o被投射到b的行上发出警告,说"Cast与给定的instanceof不兼容".这显然是正确的,但由于隐式拳击仍然有效.

现在问题是:Java规范实际上是否允许转换,因此应该适用于未来的JVM版本?或者它恰好在当前版本中工作,可能不再适用于未来的JVM更新?

java language-specifications

12
推荐指数
2
解决办法
973
查看次数

C#中外部静态构造函数的用途是什么?

根据"C#语言规范.版本5.0"的"10.12静态构造函数"部分,静态构造函数可以用"extern"修饰符标记,在这种情况下,它被称为外部静态构造函数.

普通(非外部)静态构造器是众所周知的.它们用于初始化静态字段和属性.

外部静态方法通常用于通过P/Invoke调用本机函数.

而且我也知道相当深奥的外部构造函数(另见这个问题).例如,String类有几个这样的声明,这些构造函数由运行时实现.

但是外部静态构造函数的任何实际用法是什么?我搜索了coreclr repo并没有发现任何东西.语言规范无法描述从未在野外使用的某些构造.还是可以吗?

我的猜测:C#有外部静态构造函数,因为CLR支持它们(原则上).

c# static constructor extern language-specifications

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

当简单名称和完全限定名称冲突时如何引用类

考虑以下病理示例:

class Ideone {
  static class ArrayList<T> {
    ArrayList() {
      System.out.println("!!");
    }
  }

  static class java {
    static class util {
      static class ArrayList<T> {
        ArrayList() {
          System.out.println("Here");
        }
      }
    }
  }

  public static void main(String[] args) {
    new ArrayList<>();
    new java.util.ArrayList<>();
    // Can I refer to the "usual" java.util.ArrayList?
  }
}
Run Code Online (Sandbox Code Playgroud)

在构造函数中创建的两个实例是嵌套类.

但是我怎么能java.util.ArrayList在同一个班级中提到我们都知道和喜欢的东西呢?我们无法导入它,并且我们不能使用完全限定名称,因为将使用嵌套类符号.

在这种情况下我们能做些什么?(除了明显的 - 停止使用嵌套类的这些肆无忌惮的邪恶名称).

java language-specifications

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

有关C#语言规范中隐式转换的问题

6.1节隐式转换因此定义了身份转换:

身份转换从任何类型转换为相同类型.存在这种转换,使得已经具有所需类型的实体可以说可转换为该类型.

现在,这些句子的目的是什么?

(在§6.1.6隐式参考转换中)

隐式引用转换是:

  • [...]
  • 从任何引用类型引用类型, T如果它具有隐式标识或引用转换为引用类型 T0T0具有标识转换为T.

和:

(在§6.1.7拳击转换中)

  • 如果值类型具有I到接口类型I0的装箱转换并且I0具有到的标识转换,则值类型具有到接口类型的装箱转换I.

最初它们似乎是多余的(同义词).但他们必须出于某种目的,所以为什么他们在那里?

你能给两种类型的例子T1,T2,使得T1不会是隐式转换为T2,如果不是因为上面引述的段落?

c# language-features language-specifications implicit-conversion

11
推荐指数
2
解决办法
794
查看次数

为什么函数内部允许"do"?

我注意到以下代码在VS 2013中编译并运行:

let f() =
    do Console.WriteLine(41)
    42
Run Code Online (Sandbox Code Playgroud)

但是在查看F#3.0规范时,我找不到任何提及do这种方式的用法.据我所知,do可以有以下用途:

  • 作为循环的一部分(例如),这不是这种情况.while expr do expr done
  • 内部计算表达式,例如:

    seq {
        for i in 1..2 do
        do Console.WriteLine(i)
        yield i * 2
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这不是这里的情况,f也不包含任何计算表达式.

    虽然让我困惑的是,根据规范,do应该遵循in.in由于轻量级语法,这应该是可选的,但是在此处添加它会导致编译错误("不完整表达式中的"意外令牌").

  • 模块或类中的语句.这也不是这里的情况,do它位于函数内部,不在模块或类中.

我也注意到,#light "off"代码没有编译("绑定中的Unexpected关键字'do'),但我没有找到任何可以在轻量级语法部分解释这一点的东西.

基于这一切,我会假设do在函数内部使用这种方式不应该编译,但确实如此.我是否错过了规范中的内容?或者这实际上是编译器或规范中的错误?

f# language-specifications

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

在何处指定是否应在Haskell实现中允许Unicode标识符?

我想在Haskell中用标识符中的Unicode字符(非拉丁语)编写一些教育代码.(因此,对于除英语之外的自然语言的说话者而言,标识符看起来不错且自然,在写作中没有使用拉丁字符.)因此,我开始寻找适当的Haskell实现来实现这一点.

但是语言规范中指定了哪个功能?在寻找符合要求的实现时,我将如何引用此功能?(已知哪些Haskell实现支持Unicode标识符?)

事实证明,一个Haskell实现确实接受了带有Unicode标识符的代码,而另一个Hatsell实现未能接受它.我希望如果有一种方法可以用语言特征切换的形式来形式化我的代码的这个要求,那么如果我或其他人试图运行我的代码,那么将立即清楚他的实现是否缺失所需的功能,因此他应该寻找另一个.(可能还有一个用于此功能的维基页面 - "Unicode标识符",它将列出哪些现有实现支持它,以便在需要时可以知道去哪里.)

(顺便说一下,我在这个问题上加上了一个"语法"标签,但我实际上认为它是一个lexing级别的问题,比语言的语法更低.这里有一个标签用于lexing的特征语言的级别,而不是语言的语法规范的功能?)

syntax multilingual haskell language-implementation language-specifications

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

Objective-C 2.0 ABI规范

Objective-C 2.0 ABI的文档是否存在于Internet上的某个位置?该发行说明objc4-493.9说:

即将出版的文档将仅描述使用编译器和开发人员工具的ABI.

它已经发布了吗?最接近的此类引用是Apple的Objective-C运行时引用,但这仅描述面向公众的API而不是实现细节.事实上,它甚至提到了ABI:

此外,新的Objective-C ABI(此处未描述)[...]

不幸的是,新的ABI在上述文本中没有超链接.:-)是我唯一的选择,以了解objc4运行时和Clang的CGObjCNonFragileABIMac代码生成项目的源代码?

objective-c abi language-specifications

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

运行时类型与编译时类型方法调用

C#4.0规范如下:

调用虚方法时,进行该调用的实例的运行时类型决定了要调用的实际方法实现.在非虚方法调用中,实例的编译时类型是决定因素.

起初,我认为这与初始化有关.例如,给定两个初始化:

BaseClass bcDerived = new Derived(); VS BaseClass bcBase = new BaseClass();

和辅助类中的重载:

public virtual void Method(Derived d)
{
     Console.WriteLine("Result = derived called");
}

public virtual void Method(BaseClass d)
{
     Console.WriteLine("Result = base called");
}
Run Code Online (Sandbox Code Playgroud)

Methodvirtual在这种情况下,invokation不受关键字的影响.无论是否标记virtual,都会调用派生次数最少的重载.仅在overrideDerived类中,方法调用才会更改.

那么,"运行时类型"和"编译时类型"是什么意思呢?它们如何影响方法调用?

c# language-specifications

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