- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
program test integer :: i enum, bind (c) enumerator :: enum end enum print*, KIND(i), KIND(enum) end program test
When compiled with ifort (IFORT) 15.0.3 20150407 and -i8 option, the kind of the enumerator does not match the kind of the default integer (4 vs. 8). Shouldn't the enumerator also be of kind 8? I have not tried compiling with the latest ifort. Also, I tried the following but it threw compiler errors.
program test integer :: i enum (kind=8), bind (c) enumerator :: enum end enum print*, KIND(i), KIND(enum) end program test
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Nope. Enumerators are always kind C_INT. There is no syntax to change it. The standard says:
For an enumeration, the kind is selected such that an integer type with that kind is interoperable (15.3.2) with the corresponding C enumeration type. The corresponding C enumeration type is the type that would be declared by a C enumeration specifier (6.7.2.2 of ISO/IEC 9899:1999) that specified C enumeration constants with the same values as those specified by the enum-def , in the same order as specified by the enum-def .
I don't have a C standard handy, but one reference I found says:
In ANSI C, the expressions that define the value of an enumerator constant always have int type; thus, the storage associated with an enumeration variable is the storage required for a single int value. An enumeration constant or a value of enumerated type can be used anywhere the C language permits an integer expression.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
By the way, if you no longer want to be (name withheld), go to the Dashboard (click on your name in the upper right and then Dashboard), and then edit your profile (I think it's a gear icon) to set a "Display Name".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Thanks again for a quick response (not the first time you have saved my rear). In regard to the display name, I see nothing wrong with my profile. I followed your instructions and my display name is set to what I want it to be. Maybe I am missing something else.
For the enumerator, it seems strange that the following code will compile with -i4 but not -i8. I guess I should specify the precision of the dummy enumerator in the function?
module modul interface foobar module procedure foo1 module procedure foo2 end interface foobar contains subroutine foo1 (dmy_enum) integer :: dmy_enum print*, KIND (dmy_enum) end subroutine foo1 subroutine foo2 (dmy_flt) real :: dmy_flt end subroutine foo2 end module modul program test use modul integer :: i enum, bind (c) enumerator :: enum end enum print*, KIND(i), KIND(enum) call foobar (enum) end program test
I guess I have to explicitly state that the argument to foo1 is always single precision
integer (kind=4) :: dmy_enum
this would override anything specified on the command line, correct?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quick response, seems the display name is good to go, even though I didn't set anything... strange.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The IDZ admins just changed things a bit so that it is ok if your display name is your login ID, as long as it isn't an email address. (And also as long as you're not an Intel employee.)
As I said above, an enum is always kind C_INT, which is 4 in our implementation. If you pass it to a routine that accepts it as "default integer" and change that default to kind 8, you have a kind mismatch and an error that is caught through the use of explicit interfaces here.
I recommend against using numbers as kinds, as it is not portable. If you're using ENUMs, it's probably best to use C_INT from ISO_C_BINDING. Elsewhere you can use SELECTED_INT_KIND or one of the values from ISO_FORTRAN_ENV as appropriate. A common practice is to have a "Kinds" module that declares PARAMETER constants for the various kinds to be used in the program, and then using the named constants throughout.
And lastly, you're not really specifying precision here, but kind - for integer types that affects the range in the model - precision for integers isn't meaningful.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Yes, I agree. And I am doing exactly as you say with the KIND module. I set the default integer kind to INT32 or INT64 depending on a switch at compile time. I use to have all my integers set to {{{integer (INT32)}}} or {{{integer (INT64)}}} but now I have to distinguish between integers and enumerators. I am now setting all enumerators to INT32 regardless of that switch I mentioned. Are you saying that I should set all enumerators to C_INT? Is there a difference between INT32 and C_INT? I wish you could set the enumerator as the dummy argument like below.
Thanks
module modul interface foobar module procedure foo1 module procedure foo2 end interface foobar contains subroutine foo1 (dmy_enum) enumerator :: dmy_enum !<---------- declare dummy argument as enumerator, not integer. print*, KIND (dmy_enum) end subroutine foo1 subroutine foo2 (dmy_flt) real :: dmy_flt end subroutine foo2 end module modul program test use modul integer :: i enum, bind (c) enumerator :: enum end enum print*, KIND(i), KIND(enum) call foobar (enum) end program test
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Also, I looked but could not find, is there a compiler flag that will throw a warning with mixed kind operations, like multiplication/addition/sin/log?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In our implementation, INT32 and C_INT are the same. But that may not be the case everywhere. You could do this, though:
module modul interface foobar module procedure foo1 module procedure foo2 end interface foobar enum, bind(C) enumerator :: enum_proto end enum integer, parameter :: enum_kind = kind(enum_proto) contains subroutine foo1 (dmy_enum) integer(enum_kind), intent(IN) :: dmy_enum. print*, KIND (dmy_enum) end subroutine foo1
We tend not to offer warnings for standard usage that could be problematic, though I have lobbied the developers to add such, Asking for standards checking will warn you about cases that we allow as extensions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, thanks for the help! I will do something similar to what you say. I do not think i will use the prototype that you suggest mainly because we are pretty much sticking with intel (and I'll use C_INT). We use 2003/2008 extensively and even though we have put significant effort into using other compilers, non are close to as much support as intel.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page