*/ } ul /* Whole unordered list */ { } ul li /* Unordered list item */ { } ol /* Whole ordered list */ { } ol li /* Ordered list item */ { } hr {} /* ---- Some span elements --- */ sub /* Subscripts. Pandoc: H~2~O */ { } sup /* Superscripts. Pandoc: The 2^nd^ try. */ { } em /* Emphasis. Markdown: *emphasis* or _emphasis_ */ { } em > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } blockquote > p > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } blockquote > * > p > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } blockquote > p > ins > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } blockquote > * > p > ins > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } /* ---- Links (anchors) ---- */ a /* All links */ { /* Keep links clean. On screen, they are colored; in print, they do nothing anyway. */ text-decoration: none; } @media screen { a:hover { /* On hover, we indicate a bit more that it is a link. */ text-decoration: underline; } } @media print { a { /* In print, a colored link is useless, so un-style it. */ color: black; background: transparent; } a[href^="http://"]:after, a[href^="https://"]:after { /* However, links that go somewhere else, might be useful to the reader, so for http and https links, print the URL after what was the link text in parens */ content: " (" attr(href) ") "; font-size: 90%; } } /* ---- Images ---- */ img { /* Let it be inline left/right where it wants to be, but verticality make it in the middle to look nicer, but opinions differ, and if in a multi-line paragraph, it might not be so great. */ vertical-align: middle; } div.figure /* Pandoc figure-style image */ { /* Center the image and caption */ margin-left: auto; margin-right: auto; text-align: center; font-style: italic; } p.caption /* Pandoc figure-style caption within div.figure */ { /* Inherits div.figure props by default */ } /* ---- Code blocks and spans ---- */ pre, code { background-color: #fdf7ee; /* BEGIN word wrap */ /* Need all the following to word wrap instead of scroll box */ /* This will override the overflow:auto if present */ white-space: pre-wrap; /* css-3 */ white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* Internet Explorer 5.5+ */ /* END word wrap */ } pre /* Code blocks */ { /* Distinguish pre blocks from other text by more than the font with a background tint. */ padding: 0.5em; /* Since we have a background color */ border-radius: 5px; /* Softens it */ /* Give it a some definition */ border: 1px solid #aaa; /* Set it off left and right, seems to look a bit nicer when we have a background */ margin-left: 0.5em; margin-right: 0.5em; } pre.yacc, code.yacc { background-color: #f0f0f0; } pre.yacc /* Code blocks */ { /* Distinguish pre blocks from other text by more than the font with a background tint. */ padding: 0.0em; /* Since we have a background color */ border-radius: 5px; /* Softens it */ /* Give it a some definition */ border: 0px solid #aaa; /* Set it off left and right, seems to look a bit nicer when we have a background */ margin-left: 0.0em; margin-right: 0.0em; } @media screen { pre { white-space: pre; /* Dotted looks better on screen and solid seems to print better. */ border: 1px dotted #777; } } code /* All inline code spans */ { } p > code, li > code /* Code spans in paragraphs and tight lists */ { /* Pad a little from adjacent text */ padding-left: 2px; padding-right: 2px; } li > p code /* Code span in a loose list */ { /* We have room for some more background color above and below */ padding: 2px; } span.option { color: blue; text-decoration: underline; } /* ---- Math ---- */ span.math /* Pandoc inline math default and --jsmath inline math */ { /* Tried font-style:italic here, and it messed up MathJax rendering in some browsers. Maybe don't mess with at all. */ } div.math /* Pandoc --jsmath display math */ { } span.LaTeX /* Pandoc --latexmathml math */ { } eq /* Pandoc --gladtex math */ { } /* ---- Tables ---- */ /* A clean textbook-like style with horizontal lines above and below and under the header. Rows highlight on hover to help scanning the table on screen. */ table { border-collapse: collapse; border-spacing: 0; /* IE 6 */ border-bottom: 2pt solid #000; border-top: 2pt solid #000; /* The caption on top will not have a bottom-border */ /* Center */ margin-left: auto; margin-right: auto; } thead /* Entire table header */ { border-bottom: 1pt solid #000; background-color: #eee; /* Does this BG print well? */ } tr.header /* Each header row */ { } tbody /* Entire table body */ { } /* Table body rows */ tr { } tr.odd:hover, tr.even:hover /* Use .odd and .even classes to avoid styling rows in other tables */ { background-color: #eee; } /* Odd and even rows */ tr.odd {} tr.even {} td, th /* Table cells and table header cells */ { vertical-align: top; /* Word */ vertical-align: baseline; /* Others */ padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.2em; padding-bottom: 0.2em; } /* Removes padding on left and right of table for a tight look. Good if thead has no background color*/ /* tr td:last-child, tr th:last-child { padding-right: 0; } tr td:first-child, tr th:first-child { padding-left: 0; } */ th /* Table header cells */ { font-weight: bold; } tfoot /* Table footer (what appears here if caption is on top?) */ { } caption /* This is for a table caption tag, not the p.caption Pandoc uses in a div.figure */ { caption-side: top; border: none; font-size: 0.9em; font-style: italic; text-align: center; margin-bottom: 0.3em; /* Good for when on top */ padding-bottom: 0.2em; } /* ---- Definition lists ---- */ dl /* The whole list */ { border-top: 2pt solid black; padding-top: 0.5em; border-bottom: 2pt solid black; } dt /* Definition term */ { font-weight: bold; } dd+dt /* 2nd or greater term in the list */ { border-top: 1pt solid black; padding-top: 0.5em; } dd /* A definition */ { margin-bottom: 0.5em; } dd+dd /* 2nd or greater definition of a term */ { border-top: 1px solid black; /* To separate multiple definitions */ } /* ---- Footnotes ---- */ a.footnote, a.footnoteRef { /* Pandoc, MultiMarkdown footnote links */ font-size: small; vertical-align: text-top; } a[href^="#fnref"], a.reversefootnote /* Pandoc, MultiMarkdown, ?? footnote back links */ { } @media print { a[href^="#fnref"], a.reversefootnote /* Pandoc, MultiMarkdown */ { /* Don't display these at all in print since the arrow is only something to click on */ display: none; } } div.footnotes /* Pandoc footnotes div at end of the document */ { } div.footnotes li[id^="fn"] /* A footnote item within that div */ { } table tr td,th { border-right: 1px solid; border-left: 1px solid; } /* You can class stuff as "noprint" to not print. Useful since you can't set this media conditional inside an HTML element's style attribute (I think), and you don't want to make another stylesheet that imports this one and adds a class just to do this. */ @media print { .noprint { display:none; } }
2024-12-01
integration into IS ISO/IEC 9899:202y
document number | date | comment |
---|---|---|
n3392 | 202411 | Original proposal |
n3415 | 202412 | Detailed argumentation, add recommended practice |
CC BY, see https://creativecommons.org/licenses/by/4.0
To qualify if an array is a VLA or not, the status of the array length expression of the array declarator is important. If it is an integer constant expression, the array is not a VLA and all its properties are determined at translation time. Otherwise, it is a VLA and the type expression is evaluated whenever size information is needed. In particular, type expressions of VM types where the array length expression has side effects may (or may not) be evaluated each time it is reached during execution, and thus the side effects may or may not take place.
We think that this feature is actually a bug of the specification. It seams that real world examples where side effects appear in array length expressions are rare and most often erroneous. There is a particular code pattern that may add hidden modifications to state, that is when the array length expression is a macro invocation or a function call, and when the extent to which side effects in these appear are not properly mastered.
Additionally, array length expressions with side effects have a specific caveat: evaluation order. In the following
the evaluations of the two ++i
expressions are
unsequenced, and thus the behavior of that declaration is undefined. If
such a side effect is hidden in a macro or function call
not much can be said about the array by inspecting the declaration
without prior knowledge of dimension
:
dimension
is a macro, something
like dimension(1)
could resolve to an integer constant expression and then the array is
then of known constant size. Otherwise it is a VLA.Unfortunately, the following features are often confused
Note that to determine if a type is a VM type or not, in general the distinction between link time and execution is not relevant, so in the following we will not distinguish these two cases. We are left with the following cascade of properties of array length expressions:
The goal of this papers is constrain the definitions of array declarator such that the last case never happens, but the cursor where and how to make the change has yet to be determined.
The proposed changes are normative.
The idea is to restrict possible array length expressions already syntactically as far as that is possible. The technique is similar to the one already used for “constant expression”. Namely the term is derived from “conditional expression” and then constrained further as necessary:
volatile
lvalue, so
ban them, too.Only the last point cannot always be detected at translation time; the called function may be the result of the evaluation of a modifiable function pointer, and may thus change each time the function call expression is reached. Thus this last requirement cannot easily be expressed as a constraint and possibly leads to undefined behavior if we just ban “functions with side effects”.
In the following we will assume that we would reach consensus for the first points above, and that we only have to solve the problems of whether or not we want to allow function calls, and, if so, if we want to restrict these function calls in any way, syntactically or semantically.
There is a multitude of choices that could be made to improve the situation.
The first option has the following properties:
volatile
lvalues.dimension
above a macro or a function?In essence this is an implementation-friendly but user-hostile option.
For the decision between the other possibilities, we note that none of these are exclusive in time: variant 3. could later be strengthened to variant 2., and a semantic feature could later be captured by syntax.
For this proposal, we choose the option that is the least restrictive for both, implementations and users. Namely we chose variant 3. allowing function calls that are reproducible, but leave the responsibility to check them where it is now, namely on the user side. In addition to banning direct side effects, the difference to the situation as it was before is then that implementations have guidance on the behavior that is expected, and that they may start to diagnose suspicious behavior where they can.
So we restrict the possible function calls to the properties that are
collected for the [[reproducible]]
attribute, namely of being effectless, idempotent and not having pointer
parameters that give access mutable state. This is the minimum
combination of features that is necessary for the desired
properties:
const
-qualified base
type ensures that not even modifications to state that is passed into
the function may occur.New text is underlined green, removed text is
stroke-out red.
Add a new clause 6.5’ before 6.6 (Constant expressions)
6.5’ Reproducible expressions
Syntax
reproducible-expression: conditional-expression
Description
A reproducible expression can be evaluated in any place without changing the observable program state.
Constraints
A reproducible expression shall not be or contain
- an assignment operator,
- an increment operator,
- a decrement operator,
- a conversion of an lvalue with
volatile
type.
Semantics
If a reproducible expression is evaluated and contains a function call expression, the called function shall be effectless and idempotent and no object that is pointed to by an argument of the call shall be modified.FNT)
FNT) That is, the function pointer expression of the call can be converted in place to a function pointer type with an[[reproducible]]
attribute and where all pointer parameters, if any, arerestrict
-qualified and have aconst
-qualified base type without changing the semantics of the program.
Recommended practice
In contexts that require reproducible expressions with function calls, it is recommended to use functions that are annotated with[[reproducible]]
and that have pointer parameters withconst
-qualified base types. Where this is possible, it is recommended that implementations diagnose if a function call in a reproducible expression is not effectless, not idempotent or if it modifies an object referred to by one of the arguments to the call.
Replace the grammar term assignment-expression
used in
by reproducible-expression.
If n3414 is accepted concurrently, the additions of the word “assignment” there should instead read “reproducible”.