# Writeln c\_ptr(c\_char)

**URL:** <https://chapel.discourse.group/t/writeln-c-ptr-c-char/27776>\
**Category:** Users\
**Created:** [October 19, 2023, 5:01pm UTC](https://chapel.discourse.group/t/writeln-c-ptr-c-char/27776 "2023-10-19T17:01:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![geenweb](https://avatars.discourse-cdn.com/v4/letter/g/22d042/32.png) [@geenweb](https://chapel.discourse.group/u/geenweb)\
**Post date:** [October 19, 2023, 5:01pm UTC](https://chapel.discourse.group/t/writeln-c-ptr-c-char/27776/1 "2023-10-19T17:01:43Z")

</div>

Hi,

chpl version 1.32.0

Can writeln print the value of a c\_ptr(c\_char) string? The output of the very simple test case below is:

> char\_ptr wrote \>Hello?\< to str.  
> str = 0x7fd5a00119d0

This looks like writeln prints the address of str, not it's value. I'm new to Chapel and just wondering if I'm missing a writeln option.

Thanks

```Chapel
use CTypes;

// chpl -o char_ptr char_ptr.chpl

// List ".o" and ".h" files for all C functions that will be called from Chapel.
require "char_ptr.o", "char_ptr.h", "str_prnt.o", "str_prnt.h";

// List all C functions that will be called from Chapel.
extern proc char_ptr(ref str : c_ptr(c_char)) : void;
extern proc str_prnt(ref str : c_ptr(c_char)) : void;

proc main() {

    var str : c_ptr(c_char);

    char_ptr(str);
    str_prnt(str);
    writeln("str = ", str);
    }

```

```Chapel
//
// gcc -c -o char_ptr.o char_ptr.c
#include "char_ptr.h"

void char_ptr(char** str) {

    *str = (char*)malloc(32);
    strcpy(*str, "Hello?");
}

```

```Chapel
// char_ptr.h

#ifndef __EXTERN_C_CHAR_PTR_H
#define __EXTERN_C_CHAR_PTR_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void char_ptr(char** str);

#endif

```

```Chapel
//
// gcc -c -o str_prnt.o str_prnt.c
#include "str_prnt.h"

void str_prnt(char** str) {

    printf("char_ptr wrote >%s< to str.\n", *str);
}

```

```Chapel
// str_prnt.h

#ifndef __EXTERN_C_STR_PRNT_H
#define __EXTERN_C_STR_PRNT_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void str_prnt(char** str);

#endif

```

---

<div class="post-metadata">

**Author:** ![e-kayrakli](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/e-kayrakli/32/134_2.png) [@e-kayrakli](https://chapel.discourse.group/u/e-kayrakli)\
**Post date:** [October 19, 2023, 5:46pm UTC](https://chapel.discourse.group/t/writeln-c-ptr-c-char/27776/2 "2023-10-19T17:46:07Z")

</div>

Hello and welcome to Chapel's discourse!

The behavior you're seeing is expected. `writeln` prints the value of the pointer, which is just an address. This is the behavior you'd get if you want to print out a C pointer in C with `printf("%p", ...)`.

If you want to print the value stored in the address that pointer points at, you need to dereference it, again similar to what you'd need to do in C. Here's a smaller code that does that using both the `.deref()` method and accessing the 0th index of the pointer:

```Chapel
use CTypes;

proc main() {
  var myChar = 65:c_char;
  var str = c_ptrTo(myChar);

  writeln("str = ", str);
  writeln("str = ", str.deref());
  writeln("str = ", str[0]);

  var chplStr = string.createCopyingBuffer(str, length=1);
  writeln("chplStr = ", chplStr);
}

```

If you run this, you'll see that `.deref` and `[0]` versions will print out 65, which is the integral value stored in that address. Based on what you have in the rest of the code you posted, I am guessing you want to create a Chapel string from a C buffer. So, the code above also shows the way to obtain an actual Chapel string from that buffer.

- If you want to read more about Chapel strings, I recommend checking out: [Strings — Chapel Documentation 1.33](https://chapel-lang.org/docs/main/language/spec/strings.html#chapter-strings)
- The CTypes doc that has more info about C pointers: [CTypes — Chapel Documentation 1.33](https://chapel-lang.org/docs/main/modules/standard/CTypes.html)

Hope this helps,  
Engin

---

<div class="post-metadata">

**Author:** ![geenweb](https://avatars.discourse-cdn.com/v4/letter/g/22d042/32.png) [@geenweb](https://chapel.discourse.group/u/geenweb)\
**Post date:** [October 19, 2023, 6:57pm UTC](https://chapel.discourse.group/t/writeln-c-ptr-c-char/27776/3 "2023-10-19T18:57:22Z")

</div>

Thanks Engin,

I looked for a dereference function, but overlooked .deref(). Didn't think to try str[0].

Best,

Gene

---

<div class="post-metadata">

**Author:** ![bradcray](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/bradcray/32/72_2.png) [@bradcray](https://chapel.discourse.group/u/bradcray)\
**Post date:** [October 19, 2023, 7:26pm UTC](https://chapel.discourse.group/t/writeln-c-ptr-c-char/27776/4 "2023-10-19T19:26:28Z")

</div>

@geenweb : Tagging onto Engin's response, I'll mention that there has been at least a little bit of discussion about whether Chapel's default way of writing out a ` c_ptr(c_char)` should be more string-y rather than pointer-y by default. For example, [this comment](https://github.com/chapel-lang/chapel/issues/22901#issuecomment-1670404411) touches on the question. If you had strong opinions on the topic, that would be interesting to know, either here, or you could feel free to comment on the issue itself.

Thanks,  
-Brad

---

<div class="post-metadata">

**Author:** ![geenweb](https://avatars.discourse-cdn.com/v4/letter/g/22d042/32.png) [@geenweb](https://chapel.discourse.group/u/geenweb)\
**Post date:** [October 23, 2023, 2:49pm UTC](https://chapel.discourse.group/t/writeln-c-ptr-c-char/27776/5 "2023-10-23T14:49:34Z")

</div>

Thanks Brad,

Yes, I want to print a string, not the first character of the string. So I have a C function to print the c\_ptr(c\_char) string since I can't do that in Chapel. This of course leads to ugly code such as:

```Chapel
write("rl_file = ");
str_prnt(rl_file);
write(" ir_file = ");
str_prnt(ir_file);
write(" jc_file = ");
str_prnt(jc_file);
writeln("");

```

---

<div class="post-metadata">

**Author:** ![mppf](https://avatars.discourse-cdn.com/v4/letter/m/94ad74/32.png) [@mppf](https://chapel.discourse.group/u/mppf)\
**Post date:** [October 23, 2023, 3:17pm UTC](https://chapel.discourse.group/t/writeln-c-ptr-c-char/27776/6 "2023-10-23T15:17:18Z")

</div>

FWIW, I'd be pretty worried about making `var x: c_ptr(c_char) = ... ; writeln(x);` assume that `x` is a null terminated C string and output it similar to `printf("%s", x)`. The issue is that, in general, `c_ptr(c_char)` doesn't necessarily mean it's a null-terminated string; just that it is a pointer to some bytes. It might not be null terminated in any reasonable way, and as a result, treating it as a C string could lead to printing out a lot of useless data or even lead to an invalid memory access that causes a core dump.

That said, if you are using Chapel's formatted I/O, I do think it'd be reasonable for us to output a `c_ptr(c_char)` assuming it is a null-terminated C string, when using the `%s` format string. So I think that it'd be reasonable for this program to compile and run and output `hello`:

```chapel
use CTypes;

proc main() {
  var x: c_ptrConst(c_char) = "hello".c_str();

  writef("%s\n", x);
}

```

(At present, that program fails with a runtime error about an argument type mismatch for `writef`).
