“Static If” Considered Bjarne Stroustrup, Gabriel Dos Reis, Andrew Sutton Texas A&M University Department of Computer Science and Engineering College Station, Texas 77843

1

Introduction

The notion of static if, proposed in [1, 2], is a disaster. The feature provides a single syntax with three distinct semantic meanings, depending on the context of use, all of which break from the existing meaning attributed to the usual notation. Effectively, the adoption of static if would make programs harder to read, understand, maintain, and debug. It would also impede and possibly prevent the future development of other language features, such as concepts. Furthermore, the adoption of this feature would seriously compromise our ability to produce AST-based tools for C++, and therefore put C++ at a further disadvantage compared to other modern languages vis a vis tool support. It would make C++ a lower-level language. The purpose of this paper is to examine the negative impact of the static if proposal on C++ source code. The static if feature is designed to address a small number of recurring design problems: • conditionally included statements, • conditionally defined interfaces, and • constrained templates. Some of the problems addressed by static if are real and urgent. However, we need solutions that do not negatively affect the language, tool builders, and programmers, as we expect that this feature will. In this paper we consider motivating examples for static if and discuss its negative impacts. Thus, this paper is negative, but we are also working on positive contributions. In particular, constraints (aka “concepts lite”) addresses what we see as the major and most urgent problem targeted by the static if proposal. For examples, we rely on the static if proposals [1] and [2].

1

2

Conditional Compilation

Conditional compilation, the selective inclusion of statements in a translation unit, is a conventional example. Consider a simple example of introducing some declarations, depending on whether the size of some type, T. static if (sizeof(T)==8) { void fun(); void gun(int); } else { void gun(); typedef tx int; }

The semantics of the program are this: if sizeof(T)==8, the compiler will parse the statements in the “then” branch, and will tokenize and brace-match the declarations in the else branch. Those other declarations would be uninterpreted by the compiler. Note that unlike normal if statements, the braces enclosing the conditionally compiled statements do not introduce a new scope. Those declarations are declared into the scope enclosing the static if block. This difference makes code written using static if harder to read and understand—modulating between static and non-static ifs in a single block provides ample opportunities for confution and mistakes. The effect of this declaration is to conditionally modify the current scope with a set of new declarations. How can we know, later in the program, which version of gun we should use, or whether tx is defined or not? Any use of those declarations would also need to be wrapped. static if (sizeof(T)==8) gun(32); else gun(); static long } static tx n }

if (sizeof(T)==8) { n = x; if (sizeof(T)!=8) { = x;

Thus, the use of static_if for conditional compilation is viral. The impact of conditional parsing on program analysis tools is substantial. While the feature may be easily implemented as part of the translation process, program analysis tools have traditionally struggled with conditional declarations. The inclusion of multiple variants (via, e.g., preprocessor conditions) and simultaneous repersentation within a single program model is still an open problem in the source code analysis communities. Adopting static if will make analysis harder, not easier.

2

Better solutions for configuration and versioning are needed, and if language support is required, then it must not make analysis more difficult. Note that we are using static if and static_if more or less interchangebly. The proposals use both. We think that only static_if is viable: allowing whitespace between static and if would leave us without a reliable way of searching for static if in many programming environments. For example: static /∗ blah blah blah ∗/ if (sizeof(T)==8) { gun(32); else gun(); }

3

Static If and the Preprocessor

One use of static_if would be as an alternative to tradidional ways of compiletime source manipulation. However, traditional conditional compilation using #ifdef and macros will not disappear and it is not obvious how manageable a mixture new and old would be. It will not be easy to see if static_if is used in a piece of code. We expect that some uses would be hidden in macros. We simply cannot imagine the uses to which a combination of static_if and preprocessor tricks would be put. For example: #define SI(c) static_if (c) // ... SI(NDBUG) { int f(); // ... }

Yes, that’s silly, but we confidently predict that we will see worse. We have already heard suggestions of static_for and static_while. Can static_switch be far behind? C++ would become a low-level, unprincipled hackers’ favorite playground. In our opinion, if you want compile-time computation, look to constexpr, which does have a sane and typesafe underlying model. If we do not provide a static_for, hackers will simply make one out of static_if or fake equivalents. For example: #define nvar(n)

\

3

static_if (n>0) { int mem##n = n; nvar(n-1); }

\ \ \

So what if we don’t have recursive macros? We can fake those for any reasonable n.

4

Constraining Templates

The use of static if in templates is particularly troublesome. Consider an implementation of uninitialized_fill written using static_if. template void uninitialized_fill(It b, It e, const T& x) { static if (std::is_same::iterator_category, std::random_access_iterator_tag>::value) { assert(b <= e); } static if (std::has_trivial_copy_constructor::value) { std::fill(b, e, x); } else { // Conservative implementation for (; b != e; ++b) new(&*b) T(x); } }

The semantics of static_if are to tokenize the branch not taken. If the condition is dependent, as it is in the statements above, then the compiler must not parse either branch. Both branches are tokenized since either one could contain compiler-specific extensions—or both, or neither. That won’t be known until both branches would have been fully parsed. The actual parsing of these branches is deferred until instantiation. When the static if condition can be fully evaluated, one branch may be compiled, the other discarded. In other words, using static if inside a template would prevent the compiler from performing even the most rudimentary checks on a template definition. The static_if proposal does not address the urgent need for early (point of use) checking of template arguments and for significantly improved diagnostics. Superficially, it appears to, but really it would be a major step backwards in C++’s ability to diagnose program errors. Consider the real world impact of this design choice. The inability of the compiler to parse the branches of the compiler means that the library writer will need to instantiate every branch of the template just to ensure that the syntax is correct and that no spelling errors have been made. Today, this is done, to a large extent, by the compiler.

4

Furthermore, the adoption of static if will make it virtually impossible to introduce more principled language features later. The simple fact that static if can only tokenize code in template definitions means that any template using the feature will only ever be late-checked. It will not possible to check for typing or semantic errors within the template definition without a proper AST. One motivation given for static if is that a programmer should not have to create a new definition in order to create a logical branch in a programmer. This thinking leads to the declaration above (and several other examples in subsequent sections). We think that this is the wrong approach to generic programming. The reason to create different declarations for a function like the one above is that each imposes different requirements on its template and function arguments. We prefer to localize requirements and effectively separate concerns rather than weaving them together into a single, more verbose form. This is one reason why we (and the community at large) tend to prefer overloading and/or virtual functions rather than switch-statements for representing open sets of alternatives. Yet another form of static if is its use to constrain template arguments. For example, requirements of uninitialized_fill might be written as two constrained declarations by writing if as part of the signature. template I uninitialized_fill(I first, I last, const T& value) if (std::is_convertible::value_type>::value) { ... }

The trailing if clause enforces a requirement that T must be convertible to the value_type of I. We most strongly agree that some mechanism is needed for constraining templates, this is particular syntax leaves much to be desired. It is particularly verbose, and leaves the entire body of the template unchecked. The body must only be tokenized because the static condition could guard the instantiation against compiler-specific extensions in the nested code. That fact would only be ascertainable after the entire body is parsed. The static if feature might also be used to support overloading. Below is an implementation of advance. template void advance(I& i, int n) if (is_input_iterator::value && !is_bidirectional_iterator::value) { ... } template void advance(I& i, int n) if (is_bidirectional_iterator::value && !is_random_access_iterator::value) { ... } template

5

void advance(I& i, int n) if (is_random_access_iterator::value) { ... }

Because static if only allows for Boolean decisions, overloading on a set of overlapping constraints requires the programmer to write bounding predicates like those above (e.g., input iterator but not bidirectional, bidirectional but not random access, etc...). This model of overloading is brittle, error-prone, verbose, and defines a “closed world”. No other overloads may be considered without modifying the constraints on the existing declarations in order to ensure consistency. Declarations might be condensed using else clauses, but this is only cosmetic. template void advance(I& i, int n) if (is_input_iterator::value && !is_bidirectional_iterator::value) { ... } else if (is_bidirectional_iterator::value && !is_random_access_iterator::value) { ... } else { ... }

The problems inherent in using if as the basis for overloading remain. We need language mechanisms to support constraints on template arguments, and constraint-based overloading is urgently required. However, static if is not a good way to achieve those goals. We need language features that enable the compiler to perform additional checking, and not diminish our capabilities. We also want language features that lead to more advanced forms of (compiler and non-compiler) program analysis; static if does not satisfy that requirement. Our suggested alternative, template constraints (a.k.a., concepts-lite), is a lightweight extension of the C++ programming language that satisfies both of these requirements. The syntax is similar to what was proposed for concepts with respect to constraining template arguments (i.e., a requires clause), and we can reliably support constraint-based overloading while lowering compiletimes compared to current alternatives. The design of concepts-lite is such that future extensions (i.e., concepts) and extern program analyses will be readily supported. This work is being presented in the WG21 Bristol meeting.

5

In Class Scope

The static if feature is also available inside class scope. A number of possible applications have been presented. Below is an example of a metafunction for computing factorials. template struct factorial {

6

static enum } else enum } };

if (n <= 1) { : unsigned long { value = 1 }; { : unsigned long { value = factorial::value * n };

This seems like a reasonable idea, but the motivating example simply moves the complexity from one style of idiomatic programming to another and does so in a way that requires a new language feature. A better solution would be to simply use constexpr functions. A significant negative consequence of that feature is increased confusion about how to write integer metaprograms. Another suggested use is the inclusion and ordering of members. static if might be used, for example, as a means of the avoiding the usual overhead of empty base optimizations. template class dynarray { T* start_; T* finish_; static if (!is_empty::value) { A alloc_; } };

Although may seem like an elegant alternative, the impact on the class’s implementation is far less so. For example, how would we write a constructor? template dynarray::dynarray(size_t n, T value, const A& alloc) : start_(alloc.allocate(n * sizeof(T)) , finish_(start + n) { static if (!is_empty
::value) { alloc = alloc_; } }

Every access to the allocator member must be guarded by a new static if. This use of static if is viral. Note that an alternative to the use of static if or more traditional means of implementing the empty base optimization is to use a tuple. The tuple template will eliminate all of the overhead of empty classes. The use of static if might also be used to reorder data structures for tighter alignment, but this is a potentially dangerous idea that could lead to bugs that are exceptionally difficult to diagnose and fix. Being a new and realtively simple-to-use new feature, static_if would undoubtedly be used by many who have no need for the relatively small incremenatal improvement in performance offered. The library writers for which such techniques really are important, already have to tools and skills needed. 7

6

Conclusions

In this paper we consider the impact and risks of adopting static if. Some of the problems addressed by the proposed feature are real and urgent, but on balance this proposal this proposal would do much more harm than good. Language features addressing these problems must not negatively affect the language and our ability to build tools around it. Alternatives, such as our “concepts-lite” approach should be pursued instead. Like every proposal, the static if proposals can be improved, but these are fundamentally flawed so that minor improvements will not be sufficient to make them viable. We conclude that future development of static if should be abandoned.

References [1] Brown, W.E., A Preliminary Proposal for a Static if, JTC1/SC22/WG21 N3322=12-0012, Jan, 2012

ISO/IEC

[2] Sutter, H., Bright, W., and Alexandrescu, A., Proposal: static if declaration, ISO/IEC JTC1/SC22/WG21 N3329=12-0019, Jan, 2012

8

“Static If” Considered 1 Introduction -

to produce AST-based tools for C++, and therefore put C++ at a further ... The impact of conditional parsing on program analysis tools is substantial. While the ...

200KB Sizes 8 Downloads 39 Views

Recommend Documents

“Static If” Considered 1 Introduction -
Department of Computer Science and Engineering. College Station, Texas 77843 ... notation. Effectively, the adoption of static if would make programs harder.

1.If You Stay.pdf
Sign in. Page. 1. /. 1. Loading… Page 1 of 1. Bookzinga. 1. Page 1 of 1. 1.If You Stay.pdf. 1.If You Stay.pdf. Open. Extract. Open with. Sign In. Main menu. Displaying 1.If You Stay.pdf. Page 1 of 1.

STATIC 2017.pdf
Whoops! There was a problem loading more pages. Retrying... STATIC 2017.pdf. STATIC 2017.pdf. Open. Extract. Open with. Sign In. Main menu. Displaying ...

Static IP Address
Microsoft Office Project. 2010.GalaxyQuest Space Adventure.深入解析android 5.0系统 pdf.These nineamino acidsare very important StaticIP Address the human ... Fantasticfourand silver surfer.StaticIP Address.Ready for you lisa. Castle 720 s08e01.

Static Enforcement of Service Deadlines
static analysis, i.e. a type system that recognizes pulsing processes; its soundness is stated in ..... has the following algebraic characterization (symmetric laws are omitted). Lemma 2. ..... position. Journal of Computer Security, 17(5), 2009. 4.

notes-static-contract.pdf
Given an expression e in the language, and a contract t, is e ∈ t? ... Theorem 1. ... verification conditions are generated and handed over to theorem prover to ...

man-145\is-retail-considered-customer-service.pdf
man-145\is-retail-considered-customer-service.pdf. man-145\is-retail-considered-customer-service.pdf. Open. Extract. Open with. Sign In. Main menu.

[Ku], Kuribayashi considered the cohomology of the free
identity map of X. In addition, for a prime p, the mod p homotopy type of the ... homotopy fixed points space of the self-map of the classifying space BG of a ...

1 Introduction
Sep 21, 1999 - Proceedings of the Ninth International Conference on Computational Structures Technology, Athens,. Greece, September 2-5, 2008. 1. Abstract.

1 Introduction
Jul 7, 2010 - trace left on Zd by a cloud of paths constituting a Poisson point process .... sec the second largest component of the vacant set left by the walk.

1 Introduction
Jun 9, 2014 - A FACTOR ANALYTICAL METHOD TO INTERACTIVE ... Keywords: Interactive fixed effects; Dynamic panel data models; Unit root; Factor ana-.

1 Introduction
Apr 28, 2014 - Keywords: Unit root test; Panel data; Local asymptotic power. 1 Introduction .... Third, the sequential asymptotic analysis of Ng (2008) only covers the behavior under the null .... as mentioned in Section 2, it enables an analytical e

1. Introduction
[Mac12], while Maciocia and Piyaratne managed to show it for principally polarized abelian threefolds of Picard rank one in [MP13a, MP13b]. The main result of ...

1 Introduction
Email: [email protected]. Abstract: ... characteristics of the spinal system in healthy and diseased configurations. We use the standard biome- .... where ρf and Kf are the fluid density and bulk modulus, respectively. The fluid velocity m

1 Introduction
1 Introduction ... interval orders [16] [1] and series-parallel graphs (SP1) [7]. ...... of DAGs with communication delays, Information and Computation 105 (1993) ...

1 Introduction
Jul 24, 2018 - part of people's sustained engagement in philanthropic acts .... pledged and given will coincide and the charity will reap the full ...... /12/Analysis_Danishhouseholdsoptoutofcashpayments.pdf December 2017. .... Given 83 solicitors an

Abstract 1 Introduction - UCI
the technological aspects of sensor design, a critical ... An alternative solu- ... In addi- tion to the high energy cost, the frequent communi- ... 3 Architectural Issues.

1 Introduction
way of illustration, adverbial quantifiers intervene in French but do not in Korean (Kim ... effect is much weaker than the one created by focus phrases and NPIs.

1 Introduction
The total strains govern the deformed shape of the structure δ, through kinematic or compatibility considerations. By contrast, the stress state in the structure σ (elastic or plastic) depends only on the mechanical strains. Where the thermal strai

1. Introduction
Secondly, the field transformations and the Lagrangian of lowest degree are .... lowest degree and that Clay a = 0. We will show ... 12h uvh = --cJ~ laVhab oab.

1 Introduction
Dec 24, 2013 - panel data model, in which the null of no predictability corresponds to the joint restric- tion that the ... †Deakin University, Faculty of Business and Law, School of Accounting, Economics and Finance, Melbourne ... combining the sa