Inline Variables. Document Number: N4424 Date: 2015 04 07 Hal Finkel (hfinkel@anl.gov) and Richard Smith (richard@metafoo.co.

Similar documents
Comp151. Definitions & Declarations

C++ INTERVIEW QUESTIONS

sqlpp11 - An SQL Library Worthy of Modern C++

Embedded Programming in C/C++: Lesson-1: Programming Elements and Programming in C

The C Programming Language course syllabus associate level

A deeper look at Inline functions

ECE 341 Coding Standard

MISRA-C:2012 Standards Model Summary for C / C++

C++FA 3.1 OPTIMIZING C++

Keywords are identifiers having predefined meanings in C programming language. The list of keywords used in standard C are : unsigned void

COMP 356 Programming Language Structures Notes for Chapter 10 of Concepts of Programming Languages Implementing Subprograms.

CSCI 253. Object Oriented Programming (OOP) Overview. George Blankenship 1. Object Oriented Design: Java Review OOP George Blankenship.

Object Oriented Software Design II

Programming languages C

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

MSP430 C/C++ CODE GENERATION TOOLS Compiler Version 3.2.X Parser Error/Warning/Remark List

Explicit Flow Control: break label, goto case and explicit switch

explicit class and default definitions revision of SC22/WG21/N1582 = and SC22/WG21/ N

Efficient representation of integer sets

Coding Standard for Java

Storage Classes CS 110B - Rule Storage Classes Page 18-1 \handouts\storclas

Top 10 Bug-Killing Coding Standard Rules

Qt Signals and Slots. Olivier Goffart. October 2013

Compile Time and Run Time Performance with the Sun C++ Compiler

C and C++: Case Studies in Compatibility

How To Port A Program To Dynamic C (C) (C-Based) (Program) (For A Non Portable Program) (Un Portable) (Permanent) (Non Portable) C-Based (Programs) (Powerpoint)

1 Abstract Data Types Information Hiding

Applied Informatics C++ Coding Style Guide

C++ Programming Language

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

Getting Started with the Internet Communications Engine

OpenACC 2.0 and the PGI Accelerator Compilers

Coding Rules. Encoding the type of a function into the name (so-called Hungarian notation) is forbidden - it only confuses the programmer.

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON

Chapter 7 Accessing Microcontroller Registers

Static vs. Dynamic. Lecture 10: Static Semantics Overview 1. Typical Semantic Errors: Java, C++ Typical Tasks of the Semantic Analyzer

Functions and Parameter Passing

Course Name: ADVANCE COURSE IN SOFTWARE DEVELOPMENT (Specialization:.Net Technologies)

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

Short Notes on Dynamic Memory Allocation, Pointer and Data Structure

Coding conventions and C++-style

Designing with Exceptions. CSE219, Computer Science III Stony Brook University

Recursion vs. Iteration Eliminating Recursion

Chapter 13 Storage classes

C Interview Questions

N3458: Simple Database Integration in C++11

13 Classes & Objects with Constructors/Destructors

CS 241 Data Organization Coding Standards

Answers to Review Questions Chapter 7

Conversion Constructors

C Programming Review & Productivity Tools

Stack Allocation. Run-Time Data Structures. Static Structures

Object Oriented Software Design II

To Java SE 8, and Beyond (Plan B)

Generating Serialisation Code with Clang

How Safe does my Code Need to be? Shawn A. Prestridge, Senior Field Applications Engineer

Chapter 1 Fundamentals of Java Programming

An Incomplete C++ Primer. University of Wyoming MA 5310

GENERIC and GIMPLE: A New Tree Representation for Entire Functions

CS104: Data Structures and Object-Oriented Design (Fall 2013) October 24, 2013: Priority Queues Scribes: CS 104 Teaching Team

MPLAB TM C30 Managed PSV Pointers. Beta support included with MPLAB C30 V3.00

Introduction to Distributed Computing using CORBA

A Module System for C++ (Revision 3)

Guide to Performance and Tuning: Query Performance and Sampled Selectivity

: provid.ir

Reading and Writing PCD Files The PCD File Format The Grabber Interface Writing a Custom Grabber PCL :: I/O. Suat Gedikli, Nico Blodow

Why you shouldn't use set (and what you should use instead) Matt Austern

El Dorado Union High School District Educational Services

C++FA 5.1 PRACTICE MID-TERM EXAM

CORBA Programming with TAOX11. The C++11 CORBA Implementation

Java Interfaces. Recall: A List Interface. Another Java Interface Example. Interface Notes. Why an interface construct? Interfaces & Java Types

Chapter 1 Java Program Design and Development

Common Beginner C++ Programming Mistakes

JOINT STRIKE FIGHTER. December 2005

Chapter One Introduction to Programming

MPLAB Harmony System Service Libraries Help

OpenCL Static C++ Kernel Language Extension

C++ for Safety-Critical Systems. DI Günter Obiltschnig Applied Informatics Software Engineering GmbH

LS.6 Solution Matrices

Introduction to C++ Introduction to C++ Week 7 Dr Alex Martin 2013 Slide 1

UML for C# Modeling Basics

Binary storage of graphs and related data

C++ Crash Kurs. C++ Object-Oriented Programming

Object-Oriented Design Lecture 4 CSU 370 Fall 2007 (Pucella) Tuesday, Sep 18, 2007

An Overview of Java. overview-1

CSI33 Data Structures

Debugging. Common Semantic Errors ESE112. Java Library. It is highly unlikely that you will write code that will work on the first go

Chapter 4 OOPS WITH C++ Sahaj Computer Solutions

COMP 110 Prasun Dewan 1

Real SQL Programming. Persistent Stored Modules (PSM) PL/SQL Embedded SQL

JAVA - QUICK GUIDE. Java SE is freely available from the link Download Java. So you download a version based on your operating system.

Implementation Aspects of OO-Languages

Software Engineering Concepts: Testing. Pointers & Dynamic Allocation. CS 311 Data Structures and Algorithms Lecture Slides Monday, September 14, 2009

public static void main(string[] args) { System.out.println("hello, world"); } }

OpenMP Application Program Interface

Module 10. Coding and Testing. Version 2 CSE IIT, Kharagpur

Databasesystemer, forår 2005 IT Universitetet i København. Forelæsning 3: Business rules, constraints & triggers. 3. marts 2005

Moving from CS 61A Scheme to CS 61B Java

C++ Front End Internal Documentation (excerpt)

Chapter 5 Names, Bindings, Type Checking, and Scopes

Transcription:

Document Number: N4424 Date: 2015 04 07 Hal Finkel (hfinkel@anl.gov) and Richard Smith (richard@metafoo.co.uk) Inline Variables Introduction C++ generally requires all extern functions and variables to have exactly one definition in the program, and has long provided a facility to relax this requirement for functions via the inline specifier. inline functions can be defined in multiple translation units (and must be defined in all translation units in which they are odr used), but all such definitions must be the same. The same is true (through a different mechanism) for functions and variables instantiated from templates. No such facility exists for non template variables, however, and as a result, all non template static class data members need to be explicitly defined in some translation unit. This is true even if all other definitions associated with the class can reside in header files that make minimal use of the preprocessor. However, it is not uncommon to desire the existence of a globally unique object without having to pick a single translation unit in which to define it. As a practical matter, making this choice generally requires either the use of non trivial preprocessor macros, separately compiled libraries, or both. However, one strength of C++ is its ability to support the development of header only libraries. In this vein, the lack of the ability to define an inline variable poses a significant constraint on library design. Three partial workarounds currently exist. The first is to use an inline getter function that defines a static local variable. 7.1.2p4 already requires that "A static local variable in an 1 extern inline function always refers to the same object." Thus, a getter function that returns a reference to a static local variable declared within it can provide a multiply defined global object. Drawbacks to this approach include: (a) The introduction of otherwise unnecessary functions (and associated function call operators) and (b) The object won't be constructed until the getter function is first called (6.7p4) (which rules out some use cases discussed below). The second workaround is to use a static data member of a class template or a variable template, as definitions of these are allowed to appear in multiple translation units (3.2p6). Drawbacks to this approach include: (a) The introduction of otherwise unnecessary template parameters and (b) The requirement of a use of the object to force its existence (14.7.1p2) (which rules out some use cases discussed below). 1 This is also implied by 3.2p6, for an inline function definition D appearing in multiple translation units, the behavior is as if there were a single definition of D.

The third workaround is to use a lifetime extended temporary bound to a static reference data member of a class: struct A { constexpr static auto &&kfoo = createobject(); This works because it is not possible to odr use a reference that is initialized by a constant expression so no definition of kfoo is required, and an implementation is required to act as if there was only one definition of the surrounding class so the program contains only a single temporary object. However: (a) it requires that the initializer of the object is a constant expression, (b) it is an extremely obscure technique that is hard to understand even once explained, and (c) it does not work in practice on many C++ implementations. The currently available workarounds cannot be used with objects that have useful side effects simply as a result of being created (process monitoring objects, for example). Such an object fulfills its role simply by being constructed, and must not need to be explicitly used elsewhere. The workaround of using a static local variable in an extern inline function does not work for this because a caller of the function is required to trigger the construction. The workaround of using a templated variable also does not work because, as 14.7.1p2 says, "the initialization (and any associated side effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist" (and likewise for a variable template specialization). One can, of course, explicitly instantiate the variable, but such an instantiation would itself be a definition (because it would need to include an initializer) (14.7.3p13), and could only appear in one translation unit. The workaround of using a lifetime extended temporary bound to a static reference data member of a class does not work because the object initializer will not be a constant expression. Relationship to Prior Proposals The work was motivated by the presentation of N4147 at Urbana; this proposal is not based on N4147, and is substantially simpler with a more limited scope. Implementation Concerns All conforming implementations likely support the basic infrastructure necessary to implement this proposal; it is very similar to what is needed to support static local variables defined within extern inline functions and static data members of class templates. Proposed Changes In 3.1p2 change:

A declaration is a definition unless [...] it declares a non inline static data member in a class definition (9.2, 9.4), [...] In 3.2p4 change: Every program shall contain exactly one definition of every non inline function or variable that is odr used in that program; no diagnostic required. [...] An inline function or variable shall be defined in every translation unit in which it is odr used. In 3.2p6, change: There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function or variable with external linkage (7.1.2), [...] in a program provided that each definition appears in a different translation unit, and provided that the definitions [are the same] In 3.6.2p2, change: Dynamic initialization of a non local variable with static storage duration is unordered if the variable is an implicitly or explicitly instantiated specialization, or is an inline variable, and otherwise is ordered. In 7.1p1, add inline to the list of decl specifier. Add a new subclause, The inline specifier, 7.1.X, starting with this: p1: The inline specifier can be applied only to the declaration or definition of a variable or function. p2: A variable declaration with an inline specifier declares an inline variable. Move 7.1.2p2 unchanged into 7.1.X as p3. Move 7.1.2p3 into 7.1.X, split into two paragraphs, and modify as indicated: p4: A function defined within a class definition is an inline function. <paragraph break> p5: The inline specifier shall not appear on a block scope function declaration.[ Footnote ] If the inline specifier is used in a friend declaration, that declaration shall be a definition or the function shall have previously been declared inline. Move 7.1.2p4 into 7.1.X and modify as indicated: p6: An inline function or variable shall be defined in every translation unit in which it is odr used and shall have exactly the same definition in every case (3.2). [ Note : A call to the

inline function or a use of the inline variable may be encountered before its definition appears in the translation unit. end note ] If the definition of a function or variable appears in a translation unit before its first declaration as inline, the program is ill formed. If a function or variable with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An inline function or variable with external linkage shall have the same address in all translation units. [ Note : A static local variable in an extern inline function always refers to the same object (3.2). A type defined within the body of an extern inline function is the same type in every translation unit. end note ] Remove inline from the list of function specifiers in 7.1.2p1. In 9.4p2, change: The declaration of a non inline or uninitialized static data member in its class definition is not a definition and may be of an incomplete type other than cv qualified void. In 9.4p3, change: If a non volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace or equal initializer in which every initializer clause that is an assignment expression is a constant expression (5.20). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace or equal initializer in which every initializer clause that is an assignment expression is a constant expression. [ Note : In both these cases, the member may appear in constant expressions. end note ] The member shall still be defined in a namespace scope if it is not inline and is odr used (3.2) in the program and the namespace scope definition shall not contain an initializer. Except as specified above, a non inline declaration of a static data member shall not specify a brace or equal initializer. Examples A simple static data member: struct WithStaticDataMember { // This is a definition, no out of line definition is required. static inline constexpr const char *kfoo = "foo bar"; template<typename T> struct X { // This does not require an out of line definition either. static inline int x;

A monitor object: class Monitor { public: Monitor() { // Start a thread, call std::set_new_handler, etc. } // This can be declared in a common header file included in // multiple translation units, and we ll get one TheMonitor // object in the program. inline Monitor TheMonitor; Avoiding ODR violation with global constants: // This object s address is captured by an inline function, // and so must be extern, and inline is helpful here to avoid // needing to pick a translation unit for the definition. inline extern const n = 5; // This inline function takes the address of n, and so to avoid ODR violation, n must not have internal linkage. inline auto naddr() { return &n; } A class with a constexpr static data member of its own type: struct Foo { static const Foo knull; // cannot be defined here, // Foo is not yet complete int a, b, c; inline constexpr Foo::kNull = { Note that knull must be defined in the header in order to be usable in constant expressions.