How do I specify a c-string

How do I specify a c-string

I'm trying some code Steve posted years ago:

                ! Code for message box

	                ret = MessageBox (         &

	                    GetForegroundWindow(), & ! Handle to window

	                    "Hello World!"C,           & ! Text (don't forget C-string)

	                    "Example of using MessageBox"C, & ! Caption for title bar

	                    MB_ICONINFORMATION + MB_OK) ! Type flags

	

which works. In reality I want to post some useful information that is contained in a character variable but I can't figure out the correct syntax. In fact the only thing I've tried is using LOC but that doesn't compile.

              character(len=:), allocatable :: myvar
              myvar = 'Hello World!'
                ! Code for message box

	                ret = MessageBox (         &

	                    GetForegroundWindow(), & ! Handle to window

	                    LOC(myvar),           & ! Text (don't forget C-string)

	                    "Example of using MessageBox"C, & ! Caption for title bar

	                    MB_ICONINFORMATION + MB_OK) ! Type flags

	

Compiling with Intel(R) Visual Fortran Compiler XE 14.0.1.139 [Intel(R) 64]...

error #6633: The type of the actual argument differs from the type of the dummy argument.   [LOC]

 

Thanks.

18 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

You don't use LOC, you just pass myvar. But you need to set the value of myvar as "'Hello World!'C

Alternatively you could pass TRIM(myvar)//''C

Retired 12/31/2016

The "C syntax is an Intel extension, right? It's probably better to use the c_null_char variable in iso_c_binding.  Example:

use iso_c_binding,  only: c_null_char
character(len=:), allocatable :: myvar
myvar = 'Hello World!'//c_null_char

 

 

Yes, it's an extension,but so is the use of Windows API routines. I agree that use of C_NULL_CHAR is a fine approach.

Retired 12/31/2016

Quote:

Steve Lionel (Intel) wrote:

Yes, it's an extension,but so is the use of Windows API routines. I agree that use of C_NULL_CHAR is a fine approach.

 

If the C postfix on strings is a language extension why no warning when compiling using /stand:f08?

 

Because we missed adding that check. Already filed as issue DPD200246505.

Retired 12/31/2016

Fixed for a release later this year.

Retired 12/31/2016

I have also done

myvar = 'Hello world!' // CHAR(0)

or

WRITE (myvar, *) 'Hello world!', CHAR(0)

and I THINK that worked also. Would have to do some digging to know for sure. Perhaps Steve or other could comment on this approach?

The first is fine. One could also use C_NULL_CHAR from ISO_C_BINDING instead of CHAR(0).

The second will insert a blank at the beginning of myvar - I don't think you want that. You should use an explicit format rather than list-directed. It does seem a rather high-overhead method of getting the NULL in there.

Retired 12/31/2016

Thanks Steve.

You're right of course about the list-directed format in case 2. I know this well. Kind of a separate issue though so I didn't even think about it here.

A rather "high-overhead" method of getting the NULL? Maybe, but there are certainly times when one needs to WRITE something into a string--perhaps several different variable values--in which case merely adding an additional value of CHAR(0) is pretty straightforward.

I like these techniques because they're 100 percent Fortran. No USE statement required referencing something that many people would have to look up. In fact I never heard of ISO_C_BINDING, know nothing about it, and probably have no use for it.

Sure, there are cases where the WRITE makes sense. Concatenating with CHAR(0) is fine. But as for ISO_C_BINDING, if you're doing anything with null-terminated strings you are probably interfacing with C code and you'll find that useful for doing so in a standard manner.

Retired 12/31/2016

So what's non-standard about CHAR(0)?
Is it the CHAR or the '0' ?
I cannot believe that the string terminating character presently used (Hex 0) is likely to be changed in future?
Too many things would break, surely?

Are we not being somewhat paranoid that Microsoft might change the terminator in future?

I did not see anyone suggest that CHAR(0) was nonstandard.

Retired 12/31/2016

Quote:

dboggs wrote:

... In fact I never heard of ISO_C_BINDING, know nothing about it, and probably have no use for it.

ISO_C_BINDING is simply means to an end, that of a standard way of achieving interoperability with C.  This feature introduced in Fortran starting with Fortran 2003 standard is a very valuable addition in my opinion.

I would say that ISO_C_BINDING is one part of the C interoperability features of F2003. It is not the whole of it. I know that a lot of people use ISO_C_BINDING to mean C interoperability, but that's imprecise. Note that Fortran 2015 significantly extends C interoperability - I am in the middle of writing a Doctor Fortran post on this topic.

I brought up ISO_C_BINDING because it contains standard-specified definitions of things useful in interoperating with C, including named constants for things such as NULL, LF and CR.

Retired 12/31/2016

Quote:

Anthony Richards wrote:
So what's non-standard about CHAR(0)?
Is it the CHAR or the '0' ?

If it is a nice day outside, you might be better off going for a walk rather than reading this, but speaking of Fortran processors in general (rather than ifort specifically), CHAR(0) returns a character of default character kind.  There's no requirement that the default character kind be the interoperable C character kind, and there's no guarantee that the character number zero in the collating sequence for default character is the all-bits-zero null character used to terminate C strings.  CHAR(0) is standard conforming, but the behaviour of that standard conforming code fragment is processor dependent.

Finding a Fortran processor implementation where CHAR(0) doesn't do what you would expect might be a little difficult though.

I had a nice walk outside and decided that achar(0) is "righter" than char(0)..... :-)

 

This is perhaps why C_NULL_CHAR is a better choice as you're guaranteed it is the right character kind. 

Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today