Passing a constant integer when function expects a pointer?

In C89/90 you can't generally do it without declaring a new variable. The thing about pointers in C is that they always point to lvalues. Lvalue is something that has a location in memory.

So, in order to supply the proper argument to your function, you need something that has a location in memory. That normally requires a definition, i.e. An object, a variable.

Constants in C are not lvalues, so you can't use a constant there. Things that lie somewhat in between constants and variables are literals . C89/90 has only one kind of literal: string literal .

String literals are lvalues, but not variables. So, you can use a string literal as the second argument of write .

Up vote 3 down vote favorite share g+ share fb share tw.

C pointers casting link|improve this question asked May 24 '11 at 21:15Falmarri11.6k31347 77% accept rate.

4 Your "I know I can do ..." example is incorrect. You want to say char I = 1; write(fd, &i, 1);. – Rob?

May 24 '11 at 21:17 @Rob: Yes, you're right about the char. I'm only ever writing a 1 or a 0 in this case (it's a control line) so I guess I overlooked the fact that it's incorrect-but-working. – Falmarri May 24 '11 at 21:56 let me guess ... you have a little endian machine, right?

– pmg May 24 '11 at 22:39 1 "incorrect-but-working" - something else I'll try to work into a bug triage (see stackoverflow.com/questions/6114684/…). Soon I'll be knocking 'em dead in that meeting. – Michael Burr May 24 '11 at 22:42.

In C89/90 you can't generally do it without declaring a new variable. The thing about pointers in C is that they always point to lvalues. Lvalue is something that has a location in memory.

So, in order to supply the proper argument to your function, you need something that has a location in memory. That normally requires a definition, i.e. An object, a variable.

Constants in C are not lvalues, so you can't use a constant there. Things that lie somewhat in between constants and variables are literals. C89/90 has only one kind of literal: string literal.

String literals are lvalues, but not variables. So, you can use a string literal as the second argument of write. In C99 the notion of literal was extended beyond string literals.

In C99 you can also use compound literals for that purpose, which also happen to be lvalues. In your example you can call your function as write(fd, (char) { 1 }, 1) But this feature is only available in C99.

1, I didn't know this. Too bad GCC still defaults to C90, but at least Intel C compiles this without extra flags. – larsmans May 24 '11 at 21:32 2 Nice.

To spell out the C90 solution described: write( fd, "\x1", 1);. I might actually use that sometime; I'm not sure if I'm happy about that. – Michael Burr May 24 '11 at 21:51 Is there any advantage of doing that C99 method?

Other than the obvious fact that you don't need an extra variable? That is, over say @Michael Burr's version with the string constant? – Falmarri May 24 '11 at 22:11 I selected this as it is the most direct answer to my question.

However, I probably wouldn't use this method unless there's a really good argument for it, which I don't see there being. – Falmarri May 24 '11 at 18:47.

For the specific case you cite, you can do this: write(fd, "\001", 1); But, more generally, you must do that about which you are complaining. You must declare an object before taking its address: SomeType i; SomeFUnction(&i).

Note that my answer only correct w.r. T C90. For a good example of how to use new-fangled C99, see @AndreyT.

– Rob? May 24 '11 at 21:49 1 I think this is clearer than the C99 option (and will work in C90, C99, or C++). I'm not sure I'd endorse using it.

But as I alluded to in a comment to AndreyT's answer, now that I've seen it I probably will. – Michael Burr May 24 '11 at 21:57.

Yes, that's necessary. There's no other way to do this in C that is equally clear, since you can't take the address of/get a pointer to a temporary. (And, as @rob already said, you should take the address of a char.

Your example is non-portable. ) EDIT: See @AndreyT's answer and set your compiler to C99 mode.

An integer isn't a pointer. If you pass it a one, it will dereference virtual address 1 and die. You must make that variable and pass its address.

Write requires an address as is second parameter - live with it.

I have no problem "living with it". I was just curious since I feel like this is a fairly common case. – Falmarri May 25 '11 at 18:45.

You can use drprintf() which prints to a file descriptor. It is similar to fprintf() which prints to a FILE *. Int dprintf(int fd, const char *format, ...); See man 3 dprintf for details.

The functions dprintf() and vdprintf() (as found in the glibc2 library) are exact analogs of fprintf(3) and vfprintf(3), except that they output to a file descriptor fd instead of to a stdio stream. It is POSIX.1 compliant, not universal.

Umm, I'm not sure how this answers my question. – Falmarri May 24 '11 at 22:12 You want to write a single byte without using a temporary variable. You can do that: dprintf(fd,"%c",1);.

– Notinlist May 25 '11 at 7:57 Ah, I was spacing out. Since I'm writing to a serial line, I'm pretty set on using write instead of the higher level io functions. As it's my understanding that there is less buffering involved than in fprintf and the like (unless I'm mistaken) – Falmarri May 25 '11 at 18:48.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions