1

I want to pass an argument to a function, which takes a const char **

#include<iostream>

using namespace std;

void testFunc(const char **test){}

string testString = "This is a test string";

int main()
{
    const char *tempC = testString.c_str();

    testFunc(&tempC);

    return 0;
}

This code works fine, But I dont want to go through the temporary variable tempC. I want to pass testString.c_str() directly. Like the following,

int main()
{    
    testFunc(&testString.c_str());

    return 0;
}

But, it shows error,

 error C2102: '&' requires l-value

Is it possible to do it without using the temp variable.

Quazi Irfan
  • 2,555
  • 5
  • 34
  • 69
  • 2
    You can't. Why do you need a `char**` instead of a `char*` anyways? – Marlon Jun 20 '11 at 04:48
  • Its another function which takes **const char ****, and I just need to send some data to it. I can't change the prototype. – Quazi Irfan Jun 20 '11 at 04:51
  • @iamcreasy: what does it do though? Does it sometimes change the value of test? How and why? Without knowing that, we can tell you what's wrong with what you've done, but not how to do what you want to do.... – Tony Delroy Jun 20 '11 at 05:12
  • @Tony I have posted details on the first comment of @nicol-bolas 's answer. :) – Quazi Irfan Jun 20 '11 at 05:14
  • possible duplicate of [How to convert std::string to const char **](http://stackoverflow.com/questions/6047527/how-to-convert-stdstring-to-const-char) – Tony Delroy Jun 20 '11 at 05:28
  • 1
    @iamcreasy: I've voted to close this question as I think you'll find the one above covers the same topic for the same reason. Basically, the glShaderSource function you really want to call is expecting one or more strings of input, and accepts an array of pointers to those strings. You're better off writing code that reflects that expectation and lets you add more strings easily later, even if it means having a second line of code. – Tony Delroy Jun 20 '11 at 05:32
  • @tony this may sound duplicate, and yes I can find my answer on that thread. But, look at the fantastic answer @vPulkit Gupta , @Erik Olson & @Nicol Bolas provided. And as always I'm more interested about "why" not "how". That's why my question includes my sample code, rather then asking, how to do it. I want to know, why this wont happen. Its just a coincidence that that thread has the answer of my question. – Quazi Irfan Jun 20 '11 at 13:44
  • @iamcreasy: good points... only Jason's answer on the other thread offers insight. I believe the moderators who choose which closed threads to delete take the quality of answers into account, but I'm not sure if they ever merge answers across questions. I think such questions are addressed in a S.O. FAQ somewhere - you could hunt it down if interested. – Tony Delroy Jun 21 '11 at 00:46

4 Answers4

6

I want to pass testString.c_str() directly.

You can't. std::string::c_str() returns a const char *. In order to make a pointer to a string, you have to put it in a variable and take its address.

That being said, I'm far more concerned about what function you're trying to pass this to. In general, a function that takes a const char ** does so for two reasons:

1: It takes an array of strings. You are passing a single string. Usually, C-style functions that take an array need a second parameter that says how many elements are in the array. I hope you're putting a 1 in there.

2: It is returning a string. In which case what you're doing is not helpful at all. You should create a const char * as a variable, initialize it to NULL, and then pass a pointer to it as the parameter. It's value will be filled in by the function.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Indeed. I am trying to write a function that takes a shader file as an input and turns it into a string, which I will be able to pass into the glShaderSource function. [This tutorial](http://openglbook.com/the-book/chapter-2-vertices-and-shapes) uses const char* to show it. – Quazi Irfan Jun 20 '11 at 05:05
  • @iamcreasy That's just how you have to do it. Put the return value of std::string::c_str() into a variable and take its address. Pass 1 to glShaderSource for the number of strings. – Nicol Bolas Jun 20 '11 at 05:29
2

You're going to need two temp variables to call glShaderSource, so you might as well wrap them up in one function that takes the string directly.

#include <gl.h>
#include <string>

void setShaderFromString(std::string &instr, GLuint shader)
{
        const GLchar *str[1]; // room for one const GLchar *
        GLint   len[1];       // make this an array, for symmetry

        str[0] = instr.c_str();
        len[0] = instr.length();
        glShaderSource(shader, 1, str, len);

}
Erik Olson
  • 1,154
  • 8
  • 18
  • The length array is unnecessary. If you pass NULL for the last parameter, then it will simply assume the strings are NULL-terminated. Which is what c_str generates. – Nicol Bolas Jun 20 '11 at 06:09
  • +1 Nice structured approach. Can take instr by const ref. @Nicol: sounds convenient, although trivially `length()` is O(1) and presumably avoids an O(N) operation within `glShaderSource`... ;-). – Tony Delroy Jun 20 '11 at 06:13
  • @Nicol - ok, not necessary, but we have the length, why not avoid another strlen. – Erik Olson Jun 20 '11 at 06:25
0

Simply - no.

(filling up some space)

Jim Buck
  • 20,482
  • 11
  • 57
  • 74
  • 3
    I don't believe this answer is useful. You don't provide a reason or a solution. – the_drow Jun 20 '11 at 05:08
  • Well, it directly answered his question "is it possible" and didn't have the benefit of the additional context he had since provided in the comments of other answers. – Jim Buck Jun 20 '11 at 09:04
  • It did, but it doesn't deserve to be upvoted. I don't think you can consider it as answer. Lets agree to disagree here ok? – the_drow Jun 20 '11 at 10:44
0

You can also do type-casting:

int main()
{
    testFunc((const char **)&testString);
    return 0;
}
the_drow
  • 18,571
  • 25
  • 126
  • 193
bayCoder
  • 1,345
  • 1
  • 11
  • 19
  • This assumes a STL implementation where the first member of testString happens to be a char*. Gnu libc is one. But it's not standard: static_cast(&testString) is invalid. – Erik Olson Jun 20 '11 at 16:46
  • it also assumes the pointed-to buffer is kept NUL terminated - overwhelmingly likely but not guaranteed by the C++03 Standard. Erik's concern is more practical: many reasons why an implementation might not have "the" `char*` there - small string optimisations, a pointer to a reference counted object, putting a size member first.... All up, it's really not a good idea :-/. – Tony Delroy Jun 21 '11 at 00:42
  • Can anyone give me a web reference where I can learn more about it. I want to know why this is not a good idea or / and nonstandard to use. – Quazi Irfan Jun 21 '11 at 13:29