Deducing the type of variable from its initializer expression (revision 3)

Similar documents
Deducing the type of variable from its initializer expression (revision 4)

Deducing the type of variable from its initializer expression Programming Language C++ Document no: N1721=

Decltype (revision 6): proposed wording

Decltype (revision 5)

Mechanisms for querying types of expressions: Decltype and auto revisited Programming Language C++ Document no: N1527=

New wording for C++0x Lambdas

The Syntax of auto Declarations

Proposed Wording for Variadic Templates

Operator Dot Wording

Extended friend Declarations

Proposed Wording for Variadic Templates (Revision 1)

Lambda Expressions and Closures: Wording for Monomorphic Lambdas

Appendix. Grammar. A.1 Introduction. A.2 Keywords. There is no worse danger for a teacher than to teach words instead of things.

Operator Dot Wording

Lambda Expressions and Closures: Wording for Monomorphic Lambdas (Revision 2)

American National Standards Institute Reply to: Josee Lajoie

Introduction to C++ Introduction. Structure of a C++ Program. Structure of a C++ Program. C++ widely-used general-purpose programming language

Introduction to C++ with content from

Explicit Conversion Operator Draft Working Paper

Rvalue References as Funny Lvalues

An Incomplete Language Feature

Adding Alignment Support to the C++ Programming Language / Wording

Working Draft, Extensions to C++ for Modules

Tokens, Expressions and Control Structures

A Taxonomy of Expression Value Categories

register lock_guard(mtx_); string_view s = register to_string(42); We propose register-expression to grant the temporary objects scope lifetimes.

Working Draft, C++ extensions for Concepts

C++ Module TS Issues List Gabriel Dos Reis Microsoft

Let return Be Direct and explicit

Working Draft, Extensions to C++ for Modules

Variadic Templates: Exploring the Design Space

Modules: Contexts of Template Instantiations and Name Lookup Gabriel Dos Reis Microsoft

A Fast Review of C Essentials Part II

Template Issue Resolutions from the Stockholm Meeting

Review of the C Programming Language for Principles of Operating Systems

Computer Science & Information Technology (CS) Rank under AIR 100. Examination Oriented Theory, Practice Set Key concepts, Analysis & Summary

Review of the C Programming Language

QUIZ. What is wrong with this code that uses default arguments?

Generalized Constant Expressions

Lambda Expressions and Closures: Wording for Monomorphic Lambdas (Revision 3)

Working Draft, C++ Extensions for Concepts

Agenda. The main body and cout. Fundamental data types. Declarations and definitions. Control structures

Expansion statements. Version history. Introduction. Basic usage

Type Inference auto for Note: Note:

Implicit Evaluation of auto Variables and Arguments

Working Draft, C++ Extensions for Concepts

Introduction to C++ Systems Programming

September 10,

Ch. 3: The C in C++ - Continued -

C The new standard

Programming in C and C++

G Programming Languages - Fall 2012

Class Types in Non-Type Template Parameters

Proposed Resolution to TR1 Issues 3.12, 3.14, and 3.15

CE221 Programming in C++ Part 1 Introduction

Named Requirements for C++0X Concepts

A Fast Review of C Essentials Part I

Declaration Syntax. Declarations. Declarators. Declaration Specifiers. Declaration Examples. Declaration Examples. Declarators include:

I m sure you have been annoyed at least once by having to type out types like this:

Wording for lambdas in unevaluated contexts

Abstract This paper proposes the ability to declare multiple variables initialized from a tuple or struct, along the lines of:

Structured bindings with polymorphic lambas

Definitions of scalar type and fundamental type

QUIZ. 1. Explain the meaning of the angle brackets in the declaration of v below:

Proposal for Extending the switch statement

Abstract This paper proposes the ability to declare multiple variables initialized from a tuple or struct, along the lines of:

Instantiation of Template class

Proposed Wording for Concepts (Revision 7)

Lambdas in unevaluated contexts

10. Functions (Part 2)

Merging Modules Contents

C Programming. Course Outline. C Programming. Code: MBD101. Duration: 10 Hours. Prerequisites:

BLM2031 Structured Programming. Zeyneb KURT

Introduction to Standard C++

Introduction to Move Semantics in C++ C and C

Implicit Evaluation of auto Variables and Arguments

Introduction to Core C++

Basic Types, Variables, Literals, Constants

Overload Resolution. Ansel Sermersheim & Barbara Geller Amsterdam C++ Group March 2019

a data type is Types

Lambdas in unevaluated contexts

STUDY NOTES UNIT 1 - INTRODUCTION TO OBJECT ORIENTED PROGRAMMING

Fast Introduction to Object Oriented Programming and C++

Language Design COMS W4115. Prof. Stephen A. Edwards Spring 2003 Columbia University Department of Computer Science

Advanced Systems Programming

Absolute C++ Walter Savitch

Technical Specification: Concepts

Programming 2. Object Oriented Programming. Daniel POP

The Compositional C++ Language. Denition. Abstract. This document gives a concise denition of the syntax and semantics

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

Class Types in Non-Type Template Parameters

Auto - a necessary evil?

These new operators are intended to remove some of the holes in the C type system introduced by the old C-style casts.

C++ C and C++ C++ fundamental types. C++ enumeration. To quote Bjarne Stroustrup: 5. Overloading Namespaces Classes

6.096 Introduction to C++ January (IAP) 2009

Class Types in Non-Type Template Parameters

C++11 and Compiler Update

Writing an ANSI C Program Getting Ready to Program A First Program Variables, Expressions, and Assignments Initialization The Use of #define and

A Short Summary of Javali

New Iterator Concepts

Transcription:

Deducing the type of variable from its initializer expression (revision 3) Programming Language C++ Document no: N1894=05-0154 Jaakko Järvi Texas A&M University College Station, TX jarvi@cs.tamu.edu Bjarne Stroustrup AT&T Research and Texas A&M University bs@research.att.com 2005-10-24 Gabriel Dos Reis Texas A&M University College Station, TX gdr@cs.tamu.edu 1 Introduction This document is a revision of the documents N1794=05-0054 and N1721=04-0161. The document N1721=04-0161 contained the suggested wording for new uses of keyword auto, which were unanimously approved by the evolution group meeting in Redmond, October 2004. Based on the discussions and straw-polls in the Lillehammer meeting in April 2005, wording for allowing the initialization (with auto) of more than one variables in a single statement was added; N1721=04-0161 allowed only one variable initialization per statement. The current document revises the wording of N1794=05-0054 based on technical comments from the core working group from the Lillehammer meeting and repeated reviews in the Mont-Tremblant meeting. Essentially only the suggested wording has changed from N1794=05-0054. 2 Proposed features We suggest that the auto keyword would indicate that the type of a variable is to be deduced from its initializer expression. For example: auto x = 3.14; // x has type double The auto keyword can occur as a simple type specifier (allow to be used with cv-qualifiers, *, and &) and the semantics of auto should follow exactly the rules of template argument deduction. Examples (the notation x : T in the comments is read as x has type T ): int foo(); auto x1 = foo(); const auto& x2 = foo(); auto& x3 = foo(); float& bar(); auto y1 = bar(); const auto& y2 = bar(); // x1 : int // x2 : const int& // x3 : int&: error, cannot bind a reference to a temporary // y1 : float // y2 : const float& 1

Doc. no: N1894=05-0154 2 auto& y3 = bar(); // y3 : float& A* fii() auto* z1 = fii(); // z1 : A* auto z2 = fii(); // z2 : A* auto* z3 = bar(); // error, bar does not return a pointer type A major concern in discussions of auto-like features has been the potential difficulty in figuring out whether the declared variable will be of a reference type or not. Particularly, is unintentional aliasing or slicing of objects likely? For example class B {... virtual void f(); } class D : public B {... void f(); } B* d = new D();... auto b = *d; // is this casting a reference to a base or slicing an object? b.f(); // is polymorphic behavior preserved? Basing auto on template argument deduction rules provides a natural way for a programmer to express his intention. Controlling copying and referencing is essentially the same as with variables whose types are declared explicitly. For example: A foo(); A& bar();... A x1 = foo(); auto x1 = foo(); // x1 : A // x1 : A A& x2 = foo(); auto& x2 = foo(); A y1 = bar(); auto y1 = bar(); // error, we cannot bind a non lvalue to a non const reference // error // y1 : A // y1 : A A& y2 = bar(); auto& y2 = bar(); // y2 : A& // y2 : A& Thus, as in the rest of the language, value semantics is the default, and reference semantics is provided through consistent use of &. Multi-variable declarations More than one variable can be declared in a single statement: int i; auto a = 1, *b = &i; In the case of two or more variables, both deductions must lead to the same type. Note that the declared variables can get different types, as is the case in the above example. The requirement on the type deductions to lead to the same type is best explained by translation to template argument deduction. The deductions in the above example correspond to the deductions of template parameter T below: template <class T> void foo(t a, T* b);... foo(1, &i);

Doc. no: N1894=05-0154 3 Here, T must be deduced to be the same type based on both arguments; otherwise the code is ill-defined. Direct initialization syntax Direct initialization syntax is allowed and is equivalent to copy initialization. For example: auto x = 1; auto x(1); // x : int // x : int The semantics of a direct-initialization expression of the form T v(x) with T a type expression containing an occurrence of of auto, v as a variable name, and x an expression, is defined as a translation to the corresponding copy initialization expression T v = x. Examples: const auto& y(x) -> const auto& y = x; It follows that the direct initialization syntax is allowed with new expressions as well: new auto(1); The expression auto(1) has type int, and thus new auto(1) has type int*. Combining a new expression using auto with an auto variable declaration gives: auto* x = new auto(1); Here, new auto(1) has type int*, which will be the type of x too. 3 Proposed wording Section 7.1.1 Storage class specifiers [dcl.stc] Paragraph 1 should start: The storage class specifiers are storage class specifier : auto register static extern mutable Paragraph 2 should be: The auto and register specifiers shall be applied only to names of objects declared in a block (6.3) or to function parameters (8.4). They specify It specifies that the named object has automatic storage duration (3.7.2). An object declared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default. [Note: hence, the auto specifier is almost always redundant and not often used; one use of auto is to distinguish a declaration-statement from an expression-statement (6.8) explicitly. end note] Paragraph 3 should be: A register specifier has the same semantics as an auto specifier together with is a hint to the implementation that the object so declared will be heavily used. [Note: the hint can be ignored and in most implementations it will be ignored if the address of the object is taken. end note]

Doc. no: N1894=05-0154 4 Section 7.1.5 Type specifiers [dcl.type] Paragraph 2 should read: As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration. The only exceptions to this rule are the following: const or volatile can be combined with any other type-specifier. However, redundant cv-qualifiers are prohibited except when introduced through the use of typedefs (7.1.3) or template type arguments (14.3), in which case the redundant cv-qualifiers are ignored. signed or unsigned can be combined with char, long, short, or int. short or long can be combined with int. long can be combined with double. auto can be combined with any other type specifier, except with itself. Section 7.1.5.2 Simple type specifiers [dcl.type.simple] In paragraph 1, add the following to the list of simple type specifiers: auto To Table 7, add the line: auto Change paragraph 2 to read: placeholder for a type to be deduced The auto specifier is a placeholder for a type to be deduced ([dcl.spec.auto] 7.1.5.4). The other simple-type-specifiers specify either a previously-declared user-defined type or on of the fundamental types (3.9.1). Table 7 summarizes the valid combinations of simple-type-specifiers and the types they specify. New Section 7.1.5.4 auto specifier [dcl.spec.auto] This would be a new section, even though auto is a simple type specifier. Paragraph 1 should be: The auto type-specifier has two meanings depending on the context of its use. In a decl-specifierseq that contains at least one type-specifier (in addition to auto) that is not a cv-qualifier, the auto type-specifier specifies that the object named in the declaration has automatic storage duration. The decl-specifier-seq shall contain no storage-class-specifiers. This use of the auto specifier shall only be applied to names of objects declared in a block (6.3) or to function parameters (8.4). Paragraph 2 should be: Otherwise (auto appearing with no type specifiers other than cv-qualifiers), the auto type-specifier signifies that the type of an object being declared is to be deduced from its initializer. This use of auto is allowed when declaring objects in a block [stmt.block] (6.3), in namespace scope [basic.scope.namespace] (3.3.5), or in a for-init-statement [stmt.for] (6.5.3). The decl-specifier-seq shall be followed by one or more init-declarators, each of which shall have a non-empty initializer of either of the following two forms:

Doc. no: N1894=05-0154 5 = assignment expression ( assignment expression ) Paragraph 3 should be: The auto type-specifier can also be used in declaring objects in the condition of a selection statement [stmt.select] (6.4) or of an iteration statement [stmt.iter] (6.5), and in the the type-specifier-seq in new-type-id [expr.new] (5.3.4). Paragraph 4 should be: A program that uses auto in a context not explicitly allowed in this section is ill-formed. [Example: auto x = 5; const auto *v = &x, u = 6; static auto y = 0.0; static auto int z; auto int r; end example] Paragraph 5 should be: // ok, x has type int // ok, v has type int*, u has type int // ok, y has type double // ill formed, auto and static conflict // ok, r has type int Once the type of a declarator-id has been determined according to [decl.meaning], the type of the declared variable using the declarator-id is determined from the type of its initializer using the rules for template argument deduction. Let T be the type that has been determined for a variable identifier d. Obtain P from T by replacing the occurrence of auto with a new invented type template parameter U. Let A be the type of the initializer expression for d. The type deduced for the variable d is then the deduced type determined using the rules of template argument deduction from a function call ([temp.deduct.call]), where P is a function template parameter type and A the corresponding argument type. If the deduction fails, the declaration is ill-formed. If the list of declarators contains more than one declarator, the type of each declared variable is determined as described above. If the type deduced for the template parameter U is not the same in each deduction, the program is ill-formed. [Example: const auto &i = expr; The type of i is the deduced type of the parameter u in the call f(expr) of the following invented function template: template <class U> void f(const U& u); end example] Section 8.3.4 arrays [dcl.ptr] In a declaration T D where D has the form D1 [constant expression opt]

Doc. no: N1894=05-0154 6 and the type of the identifier in the declaration T D1 is derived-declarator-type-list T, then the type of the identifier of D is an array type; if the type of the identifier of D contains the auto type deduction type-specifier, the program is ill-formed. Currently, the change is thus to ban the use of auto with arrays. This is due to arrays decaying to pointers automatically. For example: int x[5]; auto y[5] = x; Here, expression x would decay to a pointer, and would not match the type auto y[5]. Note that depending on the work on initializers we may wish to revisit this part. For example, we may wish to enable auto x[] = {a, b, c}; Also, we can debate whether the following should be allowed: int x[5]; auto y[] = x; // would this be allowed and y : int *? Section 5.3.4 New [expr.new] Add the following text after the paragraph 1 If the auto type-specifier appears in the type-specifier-seq of a new-type-id or type-id of a newexpression, the type-specifier-seq shall contain no other type-specifiers except cv-qualifiers, and the new-expression shall contain a new-initializer of the form (assignment-expression). The allocated type is deduced from the new-initializer as follows: Let (e) be the new-initializer and T be the new-type-id or type-id of the new expression, then the allocated type is the type deduced for the variable x in the invented declaration ([dcl.spec.auto]): T x = e; [Example: new auto(1); auto x = new auto( a ); // allocated type is int // allocated type is char, x is of type char* end example] 6.4. Selection statements [stmt.select] Paragraph 2 should be: The rules for conditions apply both to selection-statements and to the for and while statements (6.5). The declarator shall not specify a function or an array. The type-specifier-seq shall not contain typedef and shall not declare a new class or enumeration. If the the auto type-specifier appears in the typespecifier-seq, the type-specifier-seq shall contain no other type-specifiers except cv-qualifiers, and the type of the identifier being declared is deduced from the assignment-expression as described in ([dcl.spec.auto]).

Doc. no: N1894=05-0154 7 4 Acknowledgments We are grateful to Jeremy Siek, Douglas Gregor, Jeremiah Willcock, Gary Powell, Mat Marcus, Daveed Vandevoorde, David Abrahams, Andreas Hommel, Peter Dimov, and Paul Mensonides for their valuable input in preparing this proposal. Clearly, this proposal builds on input from members of the EWG as expressed in face-to-face meetings and reflector messages. The wording has been significantly improved as the result of careful, and repeated, reading by the members of the CWG.