Skip to content

Commit 40e8587

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

5 files changed

Lines changed: 69 additions & 30 deletions

File tree

Checks/PWR080/README.md

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

@@ -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:
@@ -138,32 +144,40 @@ the specified transformation:
138144

139145
```fortran {9,20} showLineNumbers
140146
! example.f90
147+
141148
program main
142149
use iso_fortran_env, only: real32
143150
implicit none
144151
152+
enum, bind(c)
153+
enumerator :: OPTION_HALF
154+
enumerator :: OPTION_DOUBLE
155+
enumerator :: OPTION_UNKNOWN
156+
end enum
157+
158+
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: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,34 @@ program main
44
use iso_fortran_env, only: real32
55
implicit none
66

7+
enum, bind(c)
8+
enumerator :: OPTION_HALF
9+
enumerator :: OPTION_DOUBLE
10+
enumerator :: OPTION_UNKNOWN
11+
end enum
12+
713
real(kind=real32) :: array(4)
814
array = [0.25, 0.25, 0.25, 0.25]
915

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

1218
contains
1319

1420
real(kind=real32) function transform_and_sum(array, option)
1521
implicit none
1622

1723
real(kind=real32), intent(in) :: array(:)
18-
character(len=*), intent(in) :: option
24+
integer, intent(in) :: option
1925

2026
real(kind=real32) :: sum
2127
real(kind=real32) :: factor
2228
integer :: i
2329

2430
sum = 0.0
2531

26-
if (option == "half") then
32+
if (option == OPTION_HALF) then
2733
factor = 0.5
28-
else if (option == "double") then
34+
else if (option == OPTION_DOUBLE) then
2935
factor = 2.0
3036
end if
3137

Checks/PWR080/solution.c

Lines changed: 12 additions & 6 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
10-
double factor = 1.0;
11-
if (strcmp(option, "half") == 0) {
16+
double factor = 1;
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
@@ -4,18 +4,25 @@ program main
44
use iso_fortran_env, only: real32
55
implicit none
66

7+
enum, bind(c)
8+
enumerator :: OPTION_HALF
9+
enumerator :: OPTION_DOUBLE
10+
enumerator :: OPTION_UNKNOWN
11+
end enum
12+
13+
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)