@@ -59,15 +59,21 @@ the specified transformation:
5959``` c {8,24} showLineNumbers
6060// example.c
6161#include < stdio.h>
62- #include < string.h>
6362
64- double transform_and_sum (const double * array, size_t size, const char * option) {
63+ typedef enum {
64+ OPTION_HALF,
65+ OPTION_DOUBLE,
66+ OPTION_UNKNOWN,
67+ } TransformOption;
68+
69+ double transform_and_sum (const double * array, size_t size,
70+ TransformOption option) {
6571 double sum = 0.0;
6672
6773 double factor;
68- if (strcmp( option, "half") == 0 ) {
74+ if (option == OPTION_HALF ) {
6975 factor = 0.5;
70- } else if (strcmp( option, "double") == 0 ) {
76+ } else if (option == OPTION_DOUBLE ) {
7177 factor = 2.0;
7278 }
7379
@@ -78,18 +84,13 @@ double transform_and_sum(const double *array, size_t size, const char *option) {
7884 return sum;
7985}
8086
81- int main() {
82- double array[ ] = {0.25, 0.25, 0.25, 0.25};
83- printf("Sum is: %f\n", transform_and_sum(array, 4, "unknownOption"));
8487
85- return 0;
86- }
8788```
8889
8990Note how `factor`, an automatic variable, is only explicitly initialized when
9091the received `option` is known. Since the C standard does not guarantee any
9192specific initial value, the state of `factor` is indeterminate in the previous
92- scenario (using an `unknownOption `), leading to different outcomes depending on
93+ scenario (using `OPTION_UNKNOWN `), leading to different outcomes depending on
9394the compiler and its settings:
9495
9596- For instance, `gcc -O2` behaves as if the `if` branch was taken:
@@ -138,32 +139,41 @@ the specified transformation:
138139
139140``` fortran {9,20} showLineNumbers
140141! example.f90
142+ ! PWR080: Conditionally initialized variables can lead to undefined behavior
143+
141144program main
142145 use iso_fortran_env, only: real32
143146 implicit none
144147
148+ enum, bind(c)
149+ enumerator :: OPTION_HALF
150+ enumerator :: OPTION_DOUBLE
151+ enumerator :: OPTION_UNKNOWN
152+ end enum
153+
154+
145155 real(kind=real32) :: array(4)
146156 array = [0.25, 0.25, 0.25, 0.25]
147157
148- print *, "Sum is:", transform_and_sum(array, "unknownOption" )
158+ print *, "Sum is:", transform_and_sum(array, OPTION_UNKNOWN )
149159
150160contains
151161
152162 real(kind=real32) function transform_and_sum(array, option)
153163 implicit none
154164
155165 real(kind=real32), intent(in) :: array(:)
156- character(len=*) , intent(in) :: option
166+ integer , intent(in) :: option
157167
158168 real(kind=real32) :: sum
159169 real(kind=real32) :: factor
160170 integer :: i
161171
162172 sum = 0.0
163173
164- if (option == "half" ) then
174+ if (option == OPTION_HALF ) then
165175 factor = 0.5
166- else if (option == "double" ) then
176+ else if (option == OPTION_DOUBLE ) then
167177 factor = 2.0
168178 end if
169179
@@ -180,7 +190,7 @@ end program main
180190Note how ` factor ` is only explicitly initialized when the received ` option ` is
181191known. Since the Fortran standard does not guarantee any specific initial
182192value, the state of ` factor ` is indeterminate in the previous scenario (using
183- an ` unknownOption ` ), leading to different outcomes depending on the compiler
193+ ` OPTION_UNKNOWN ` ), leading to different outcomes depending on the compiler
184194and its settings:
185195
186196- For instance, ` gfortran -O2 ` behaves as if the ` if ` branch was taken:
0 commit comments