Skip to content

Commit ffa7c05

Browse files
committed
PWR080: Simplify examples to use enumerated options
1 parent 629d868 commit ffa7c05

5 files changed

Lines changed: 71 additions & 31 deletions

File tree

Checks/PWR080/README.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,24 @@ them.
5656
Consider the following code, which sums the elements of an array after applying
5757
the specified transformation:
5858

59-
```c {8,24} showLineNumbers
59+
```c {14,30} 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

@@ -80,7 +86,7 @@ double transform_and_sum(const double *array, size_t size, const char *option) {
8086

8187
int main() {
8288
double array[] = {0.25, 0.25, 0.25, 0.25};
83-
printf("Sum is: %f\n", transform_and_sum(array, 4, "unknownOption"));
89+
printf("Sum is: %f\n", transform_and_sum(array, 4, OPTION_UNKNOWN));
8490

8591
return 0;
8692
}
@@ -89,7 +95,7 @@ int main() {
8995
Note how `factor`, an automatic variable, is only explicitly initialized when
9096
the received `option` is known. Since the C standard does not guarantee any
9197
specific initial value, the state of `factor` is indeterminate in the previous
92-
scenario (using an `unknownOption`), leading to different outcomes depending on
98+
scenario (using `OPTION_UNKNOWN`), leading to different outcomes depending on
9399
the compiler and its settings:
94100
95101
- For instance, `gcc -O2` behaves as if the `if` branch was taken:
@@ -136,34 +142,42 @@ double factor = 1.0;
136142
Consider the following code, which sums the elements of an array after applying
137143
the specified transformation:
138144

139-
```fortran {9,20} showLineNumbers
145+
```fortran {17,28} showLineNumbers
140146
! example.f90
147+
148+
module options
149+
integer, parameter :: OPTION_HALF = 1
150+
integer, parameter :: OPTION_DOUBLE = 2
151+
integer, parameter :: OPTION_UNKNOWN = 3
152+
end module options
153+
141154
program main
142155
use iso_fortran_env, only: real32
156+
use options, only: OPTION_HALF, OPTION_DOUBLE, OPTION_UNKNOWN
143157
implicit none
144158
145159
real(kind=real32) :: array(4)
146160
array = [0.25, 0.25, 0.25, 0.25]
147161
148-
print *, "Sum is:", transform_and_sum(array, "unknownOption")
162+
print *, "Sum is:", transform_and_sum(array, OPTION_UNKNOWN)
149163
150164
contains
151165
152166
real(kind=real32) function transform_and_sum(array, option)
153167
implicit none
154168
155169
real(kind=real32), intent(in) :: array(:)
156-
character(len=*), intent(in) :: option
170+
integer, intent(in) :: option
157171
158172
real(kind=real32) :: sum
159173
real(kind=real32) :: factor
160174
integer :: i
161175
162176
sum = 0.0
163177
164-
if (option == "half") then
178+
if (option == OPTION_HALF) then
165179
factor = 0.5
166-
else if (option == "double") then
180+
else if (option == OPTION_DOUBLE) then
167181
factor = 2.0
168182
end if
169183
@@ -180,7 +194,7 @@ end program main
180194
Note how `factor` is only explicitly initialized when the received `option` is
181195
known. Since the Fortran standard does not guarantee any specific initial
182196
value, the state of `factor` is indeterminate in the previous scenario (using
183-
an `unknownOption`), leading to different outcomes depending on the compiler
197+
`OPTION_UNKNOWN`), leading to different outcomes depending on the compiler
184198
and its settings:
185199

186200
- For instance, `gfortran -O2` behaves as if the `if` branch was taken:

Checks/PWR080/example.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
// PWR080: Conditionally initialized variables can lead to undefined behavior
22

33
#include <stdio.h>
4-
#include <string.h>
54

6-
double transform_and_sum(const double *array, size_t size, const char *option) {
5+
typedef enum {
6+
OPTION_HALF,
7+
OPTION_DOUBLE,
8+
OPTION_UNKNOWN,
9+
} TransformOption;
10+
11+
double transform_and_sum(const double *array, size_t size,
12+
TransformOption option) {
713
double sum = 0.0;
814

915
double factor;
10-
if (strcmp(option, "half") == 0) {
16+
if (option == OPTION_HALF) {
1117
factor = 0.5;
12-
} else if (strcmp(option, "double") == 0) {
18+
} else if (option == OPTION_DOUBLE) {
1319
factor = 2.0;
1420
}
1521

@@ -22,7 +28,7 @@ double transform_and_sum(const double *array, size_t size, const char *option) {
2228

2329
int main() {
2430
double array[] = {0.25, 0.25, 0.25, 0.25};
25-
printf("Sum is: %f\n", transform_and_sum(array, 4, "unknownOption"));
31+
printf("Sum is: %f\n", transform_and_sum(array, 4, OPTION_UNKNOWN));
2632

2733
return 0;
2834
}

Checks/PWR080/example.f90

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,38 @@
11
! PWR080: Conditionally initialized variables can lead to undefined behavior
22

3+
module options
4+
integer, parameter :: OPTION_HALF = 1
5+
integer, parameter :: OPTION_DOUBLE = 2
6+
integer, parameter :: OPTION_UNKNOWN = 3
7+
end module options
8+
39
program main
410
use iso_fortran_env, only: real32
11+
use options, only: OPTION_HALF, OPTION_DOUBLE, OPTION_UNKNOWN
512
implicit none
613

714
real(kind=real32) :: array(4)
815
array = [0.25, 0.25, 0.25, 0.25]
916

10-
print *, "Sum is:", transform_and_sum(array, "unknownOption")
17+
print *, "Sum is:", transform_and_sum(array, OPTION_UNKNOWN)
1118

1219
contains
1320

1421
real(kind=real32) function transform_and_sum(array, option)
1522
implicit none
1623

1724
real(kind=real32), intent(in) :: array(:)
18-
character(len=*), intent(in) :: option
25+
integer, intent(in) :: option
1926

2027
real(kind=real32) :: sum
2128
real(kind=real32) :: factor
2229
integer :: i
2330

2431
sum = 0.0
2532

26-
if (option == "half") then
33+
if (option == OPTION_HALF) then
2734
factor = 0.5
28-
else if (option == "double") then
35+
else if (option == OPTION_DOUBLE) then
2936
factor = 2.0
3037
end if
3138

Checks/PWR080/solution.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
// PWR080: Conditionally initialized variables can lead to undefined behavior
22

33
#include <stdio.h>
4-
#include <string.h>
54

6-
double transform_and_sum(const double *array, size_t size, const char *option) {
5+
typedef enum {
6+
OPTION_HALF,
7+
OPTION_DOUBLE,
8+
OPTION_UNKNOWN,
9+
} TransformOption;
10+
11+
double transform_and_sum(const double *array, size_t size,
12+
TransformOption option) {
713
double sum = 0.0;
814

915
// Identity transformation by default
1016
double factor = 1.0;
11-
if (strcmp(option, "half") == 0) {
17+
if (option == OPTION_HALF) {
1218
factor = 0.5;
13-
} else if (strcmp(option, "double") == 0) {
19+
} else if (option == OPTION_DOUBLE) {
1420
factor = 2.0;
1521
}
1622

@@ -23,7 +29,7 @@ double transform_and_sum(const double *array, size_t size, const char *option) {
2329

2430
int main() {
2531
double array[] = {0.25, 0.25, 0.25, 0.25};
26-
printf("Sum is: %f\n", transform_and_sum(array, 4, "unknownOption"));
32+
printf("Sum is: %f\n", transform_and_sum(array, 4, OPTION_UNKNOWN));
2733

2834
return 0;
2935
}

Checks/PWR080/solution.f90

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,28 @@
11
! PWR080: Conditionally initialized variables can lead to undefined behavior
22

3+
module options
4+
integer, parameter :: OPTION_HALF = 1
5+
integer, parameter :: OPTION_DOUBLE = 2
6+
integer, parameter :: OPTION_UNKNOWN = 3
7+
end module options
8+
39
program main
410
use iso_fortran_env, only: real32
11+
use options, only: OPTION_HALF, OPTION_DOUBLE, OPTION_UNKNOWN
512
implicit none
613

714
real(kind=real32) :: array(4)
815
array = [0.25, 0.25, 0.25, 0.25]
916

10-
print *, "Sum is:", transform_and_sum(array, "unknownOption")
17+
print *, "Sum is:", transform_and_sum(array, OPTION_UNKNOWN)
1118

1219
contains
1320

1421
real(kind=real32) function transform_and_sum(array, option)
1522
implicit none
1623

1724
real(kind=real32), intent(in) :: array(:)
18-
character(len=*), intent(in) :: option
25+
integer, intent(in) :: option
1926

2027
real(kind=real32) :: sum
2128
real(kind=real32) :: factor
@@ -25,9 +32,9 @@ real(kind=real32) function transform_and_sum(array, option)
2532
! Identity transformation by default
2633
factor = 1.0
2734

28-
if (option == "half") then
35+
if (option == OPTION_HALF) then
2936
factor = 0.5
30-
else if (option == "double") then
37+
else if (option == OPTION_DOUBLE) then
3138
factor = 2.0
3239
end if
3340

0 commit comments

Comments
 (0)