Skip to content

Commit

Permalink
Deploying to gh-pages from @ ace741f 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
rouson committed Aug 23, 2024
1 parent 35d4e12 commit 190cb59
Show file tree
Hide file tree
Showing 12 changed files with 463 additions and 361 deletions.
110 changes: 106 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ The `characterizable_t` type defines an `as_character()` deferred binding that p

The `intrinsic_array_t` type that extends `characterizable_t` provides a convenient mechanism for producing diagnostic output from arrays of intrinsic type `complex`, `integer`, `logical`, or `real`.

Documentation
-------------
See [Assert's GitHub Pages site] for HTML documentation generated with [`ford`].

Use Cases
---------
Two common use cases include
Expand Down Expand Up @@ -117,8 +113,114 @@ See the [./example](./example) subdirectory.

Documentation
-------------

See [Assert's GitHub Pages site] for HTML documentation generated with [`ford`].

For further documentation, please see [example/README.md] and the [tests]. Also, the code in [src] has comments formatted for generating HTML documentation using [FORD].

### Potential pitfalls of `call_assert` macros:

The `call_assert*` macros from the `assert_macros.h` header file provide the
attractive guarantee that they will always compile *completely* away when
assertions are disabled, regardless of compiler analyses and optimization
level. This means users can reap the maintainability and correctness benefits
of aggressively asserting invariants throughout their code, without needing to
balance any potential performance cost associated with such assertions when the
code runs in production.

Unfortunately, C-preprocessor macros do not integrate cleanly with some aspects
of the Fortran language. As such, you might encounter one or more of the
following pitfalls when using these macros.

#### Line length limit

Up to and including the Fortran 2018 language standard, compilers were only
required to support up to 132 characters per free-form source line.
Preprocessor macro invocations are always expanded to a single line during
compilation, so when passing non-trivial arguments to macros including
`call_assert*` it becomes easy for the expansion to exceed this line length
limit. This can result in compile-time errors like the following from gfortran:

```
Error: Line truncated at (1) [-Werror=line-truncation]
```

Some compilers offer a command-line argument that can be used to workaround this legacy limit, eg:

* `gfortran -ffree-line-length-0` aka `gfortran -ffree-line-length-none`

When using `fpm`, one can pass such a flag to the compiler using the `fpm --flag` option, eg:

```shell
$ fpm test --profile release --flag -ffree-line-length-0
```

Thankfully Fortran 2023 raised this obscolecent line limit to 10,000
characters, so by using newer compilers you might never encounter this problem.

#### Line breaks in macro invocations

As mentioned above, preprocessor macro invocations are always expanded to a
single line, no matter how many lines were used by the invocation. This means
it's problematic to invoke the `call_assert*` macros with code like the
following:

```fortran
! INCORRECT: don't use & line continuations!
call_assert_diagnose( computed_checksum == expected_checksum, &
"Checksum mismatch failure!", &
expected_checksum )
```
When the preprocessor expands the macro invocation above, the `&` characters
above are not interpreted as Fortran line continuations. Instead they are
inserted into the middle of the single-line macro expansion, where they will
(likely) create a confusing syntax error.

Instead when breaking long lines in a macro invocation, just break the line (no
continuation character!), eg:

```fortran
! When breaking a lines in a macro invocation, just use new-line with no `&` continuation character:
call_assert_diagnose( computed_checksum == expected_checksum,
"Checksum mismatch failure!",
expected_checksum )
```

#### Comments in macro invocations

Fortran does not support comments with an end delimiter,
only to-end-of-line comments. As such, there is no way to safely insert a
Fortran comment into the middle of a macro invocation. For example, the
following seemingly reasonable code results in a syntax error
after macro expansion:

```fortran
! INCORRECT: cannot use Fortran comments inside macro invocation
call_assert_diagnose( computed_checksum == expected_checksum, ! ensured since version 3.14
"Checksum mismatch failure!", ! TODO: write a better message here
computed_checksum )
```

Depending on your compiler it *might* be possible to use a C-style block
comment (because they are removed by the preprocessor), for example with
gfortran one can instead write the following:

```fortran
call_assert_diagnose( computed_checksum == expected_checksum, /* ensured since version 3.14 */
"Checksum mismatch failure!", /* TODO: write a better message here */
computed_checksum )
```

However that capability might not be portable to other Fortran compilers.
When in doubt, one can always move the comment outside the macro invocation:

```fortran
! assert a property ensured since version 3.14
call_assert_diagnose( computed_checksum == expected_checksum,
"Checksum mismatch failure!",
computed_checksum ) ! TODO: write a better message above
```

[Hyperlinks]:#
[OpenCoarrays]: https://github.com/sourceryinstitute/opencoarrays
[Enforcing programming contracts]: #enforcing-programming-contracts
Expand Down
76 changes: 38 additions & 38 deletions lists/files.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,34 @@ <h1>Source Files</h1>
<path fill="none" stroke="#000000" d="M156.73,-137.89C148.59,-139.1 139.8,-140.4 130.97,-141.71"/>
<polygon fill="#000000" stroke="#000000" points="130.39,-138.26 121.01,-143.18 131.41,-145.18 130.39,-138.26"/>
</g>
<!-- sourcefile~intrinsic_array_m.f90 -->
<!-- sourcefile~assert_subroutine_s.f90 -->
<g id="file~~graph~~FileGraph_node3" class="node">
<title>sourcefile~assert_subroutine_s.f90</title>
<g id="a_file~~graph~~FileGraph_node3"><a xlink:href=".././sourcefile/assert_subroutine_s.f90.html" xlink:title="assert_subroutine_s.F90">
<polygon fill="#f0ad4e" stroke="#f0ad4e" points="413,-104 274,-104 274,-80 413,-80 413,-104"/>
<text text-anchor="middle" x="343.5" y="-89.6" font-family="Helvetica,sans-Serif" font-size="10.50" fill="white">assert_subroutine_s.F90</text>
</a>
</g>
</g>
<!-- sourcefile~string_m.f90 -->
<g id="file~~graph~~FileGraph_node4" class="node">
<title>sourcefile~string_m.f90</title>
<g id="a_file~~graph~~FileGraph_node4"><a xlink:href=".././sourcefile/string_m.f90.html" xlink:title="string_m.f90">
<polygon fill="#f0ad4e" stroke="#f0ad4e" points="383,-24 304,-24 304,0 383,0 383,-24"/>
<text text-anchor="middle" x="343.5" y="-9.6" font-family="Helvetica,sans-Serif" font-size="10.50" fill="white">string_m.f90</text>
</a>
</g>
</g>
<!-- sourcefile~string_m.f90&#45;&gt;sourcefile~assert_m.f90 -->
<g id="file~~graph~~FileGraph_edge3" class="edge">
<title>sourcefile~string_m.f90&#45;&gt;sourcefile~assert_m.f90</title>
<path fill="none" stroke="#000000" d="M303.7,-22.66C293.48,-26.52 282.85,-31.57 274,-38 246.69,-57.85 223.82,-90 210.64,-111.07"/>
<polygon fill="#000000" stroke="#000000" points="207.48,-109.53 205.28,-119.89 213.47,-113.16 207.48,-109.53"/>
</g>
<!-- sourcefile~intrinsic_array_m.f90 -->
<g id="file~~graph~~FileGraph_node5" class="node">
<title>sourcefile~intrinsic_array_m.f90</title>
<g id="a_file~~graph~~FileGraph_node3"><a xlink:href=".././sourcefile/intrinsic_array_m.f90.html" xlink:title="intrinsic_array_m.F90">
<g id="a_file~~graph~~FileGraph_node5"><a xlink:href=".././sourcefile/intrinsic_array_m.f90.html" xlink:title="intrinsic_array_m.F90">
<polygon fill="#f0ad4e" stroke="#f0ad4e" points="407,-184 280,-184 280,-160 407,-160 407,-184"/>
<text text-anchor="middle" x="343.5" y="-169.6" font-family="Helvetica,sans-Serif" font-size="10.50" fill="white">intrinsic_array_m.F90</text>
</a>
Expand All @@ -148,51 +172,27 @@ <h1>Source Files</h1>
<path fill="none" stroke="#000000" d="M279.79,-167.54C235.73,-164.4 176.76,-160.2 131.22,-156.96"/>
<polygon fill="#000000" stroke="#000000" points="131.36,-153.46 121.13,-156.24 130.86,-160.45 131.36,-153.46"/>
</g>
<!-- sourcefile~assert_subroutine_s.f90 -->
<g id="file~~graph~~FileGraph_node4" class="node">
<title>sourcefile~assert_subroutine_s.f90</title>
<g id="a_file~~graph~~FileGraph_node4"><a xlink:href=".././sourcefile/assert_subroutine_s.f90.html" xlink:title="assert_subroutine_s.F90">
<polygon fill="#f0ad4e" stroke="#f0ad4e" points="413,-104 274,-104 274,-80 413,-80 413,-104"/>
<text text-anchor="middle" x="343.5" y="-89.6" font-family="Helvetica,sans-Serif" font-size="10.50" fill="white">assert_subroutine_s.F90</text>
</a>
</g>
</g>
<!-- sourcefile~assert_subroutine_m.f90 -->
<g id="file~~graph~~FileGraph_node5" class="node">
<g id="file~~graph~~FileGraph_node6" class="node">
<title>sourcefile~assert_subroutine_m.f90</title>
<g id="a_file~~graph~~FileGraph_node5"><a xlink:href=".././sourcefile/assert_subroutine_m.f90.html" xlink:title="assert_subroutine_m.F90">
<g id="a_file~~graph~~FileGraph_node6"><a xlink:href=".././sourcefile/assert_subroutine_m.f90.html" xlink:title="assert_subroutine_m.F90">
<polygon fill="#f0ad4e" stroke="#f0ad4e" points="594,-83 449,-83 449,-59 594,-59 594,-83"/>
<text text-anchor="middle" x="521.5" y="-68.6" font-family="Helvetica,sans-Serif" font-size="10.50" fill="white">assert_subroutine_m.F90</text>
</a>
</g>
</g>
<!-- sourcefile~assert_subroutine_m.f90&#45;&gt;sourcefile~assert_m.f90 -->
<g id="file~~graph~~FileGraph_edge2" class="edge">
<g id="file~~graph~~FileGraph_edge4" class="edge">
<title>sourcefile~assert_subroutine_m.f90&#45;&gt;sourcefile~assert_m.f90</title>
<path fill="none" stroke="#000000" d="M451.74,-58.98C401.12,-52.97 331.4,-50.71 274,-71 250.81,-79.2 229.52,-97.88 215.5,-112.42"/>
<polygon fill="#000000" stroke="#000000" points="212.72,-110.27 208.5,-119.99 217.86,-115.03 212.72,-110.27"/>
</g>
<!-- sourcefile~assert_subroutine_m.f90&#45;&gt;sourcefile~assert_subroutine_s.f90 -->
<g id="file~~graph~~FileGraph_edge8" class="edge">
<g id="file~~graph~~FileGraph_edge7" class="edge">
<title>sourcefile~assert_subroutine_m.f90&#45;&gt;sourcefile~assert_subroutine_s.f90</title>
<path fill="none" stroke="#000000" d="M448.91,-79.54C440.43,-80.55 431.74,-81.59 423.17,-82.61"/>
<polygon fill="#000000" stroke="#000000" points="422.69,-79.15 413.18,-83.81 423.52,-86.1 422.69,-79.15"/>
</g>
<!-- sourcefile~string_m.f90 -->
<g id="file~~graph~~FileGraph_node6" class="node">
<title>sourcefile~string_m.f90</title>
<g id="a_file~~graph~~FileGraph_node6"><a xlink:href=".././sourcefile/string_m.f90.html" xlink:title="string_m.f90">
<polygon fill="#f0ad4e" stroke="#f0ad4e" points="383,-24 304,-24 304,0 383,0 383,-24"/>
<text text-anchor="middle" x="343.5" y="-9.6" font-family="Helvetica,sans-Serif" font-size="10.50" fill="white">string_m.f90</text>
</a>
</g>
</g>
<!-- sourcefile~string_m.f90&#45;&gt;sourcefile~assert_m.f90 -->
<g id="file~~graph~~FileGraph_edge3" class="edge">
<title>sourcefile~string_m.f90&#45;&gt;sourcefile~assert_m.f90</title>
<path fill="none" stroke="#000000" d="M303.7,-22.66C293.48,-26.52 282.85,-31.57 274,-38 246.69,-57.85 223.82,-90 210.64,-111.07"/>
<polygon fill="#000000" stroke="#000000" points="207.48,-109.53 205.28,-119.89 213.47,-113.16 207.48,-109.53"/>
</g>
<!-- sourcefile~characterizable_m.f90 -->
<g id="file~~graph~~FileGraph_node7" class="node">
<title>sourcefile~characterizable_m.f90</title>
Expand All @@ -203,23 +203,23 @@ <h1>Source Files</h1>
</g>
</g>
<!-- sourcefile~characterizable_m.f90&#45;&gt;sourcefile~assert_m.f90 -->
<g id="file~~graph~~FileGraph_edge4" class="edge">
<g id="file~~graph~~FileGraph_edge2" class="edge">
<title>sourcefile~characterizable_m.f90&#45;&gt;sourcefile~assert_m.f90</title>
<path fill="none" stroke="#000000" d="M455.34,-132C394.22,-132 304.14,-132 248.51,-132"/>
<polygon fill="#000000" stroke="#000000" points="248.2,-128.5 238.2,-132 248.2,-135.5 248.2,-128.5"/>
</g>
<!-- sourcefile~characterizable_m.f90&#45;&gt;sourcefile~intrinsic_array_m.f90 -->
<g id="file~~graph~~FileGraph_edge7" class="edge">
<title>sourcefile~characterizable_m.f90&#45;&gt;sourcefile~intrinsic_array_m.f90</title>
<path fill="none" stroke="#000000" d="M467.69,-144C448.72,-148.31 427.14,-153.22 407.4,-157.7"/>
<polygon fill="#000000" stroke="#000000" points="406.55,-154.31 397.57,-159.94 408.1,-161.13 406.55,-154.31"/>
</g>
<!-- sourcefile~characterizable_m.f90&#45;&gt;sourcefile~assert_subroutine_s.f90 -->
<g id="file~~graph~~FileGraph_edge9" class="edge">
<g id="file~~graph~~FileGraph_edge8" class="edge">
<title>sourcefile~characterizable_m.f90&#45;&gt;sourcefile~assert_subroutine_s.f90</title>
<path fill="none" stroke="#000000" d="M467.69,-120C448.72,-115.69 427.14,-110.78 407.4,-106.3"/>
<polygon fill="#000000" stroke="#000000" points="408.1,-102.87 397.57,-104.06 406.55,-109.69 408.1,-102.87"/>
</g>
<!-- sourcefile~characterizable_m.f90&#45;&gt;sourcefile~intrinsic_array_m.f90 -->
<g id="file~~graph~~FileGraph_edge9" class="edge">
<title>sourcefile~characterizable_m.f90&#45;&gt;sourcefile~intrinsic_array_m.f90</title>
<path fill="none" stroke="#000000" d="M467.69,-144C448.72,-148.31 427.14,-153.22 407.4,-157.7"/>
<polygon fill="#000000" stroke="#000000" points="406.55,-154.31 397.57,-159.94 408.1,-161.13 406.55,-154.31"/>
</g>
</g>
</svg>
</div><div><a type="button" class="graph-help" data-toggle="modal" href="#graph-help-text">Help</a></div><div class="modal fade" id="graph-help-text" tabindex="-1" role="dialog"><div class="modal-dialog modal-lg" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" id="-graph-help-label">Graph Key</h4></div><div class="modal-body">
Expand Down
Loading

0 comments on commit 190cb59

Please sign in to comment.