how to define a var in C++ - string

This code compiles perfect:
if ( args.Length() > 0 ) {
if ( args[0]->IsString() ) {
String::Utf8Value szQMN( args[0]->ToString() ) ;
printf( "(cc)>>>> qmn is [%s].\n", (const char*)(* szQMN) ) ;
} ;
} ;
But this one does not :
if ( args.Length() > 0 ) {
if ( args[0]->IsString() ) {
String::Utf8Value szQMN( args[0]->ToString() ) ; // <<<< (A)
} ;
} ;
printf( "(cc)>>>> qmn is [%s].\n", (const char*)(* szQMN) ) ; // <<<< (B)
Error says : "error C2065: 'szQMN' : undeclared identifier" on line (B)
This means to me that the sentence marked (A) is a definition at the same time as an assignement, right ?
And compiler decides it is "conditionally" defined as it is within two "IF's" ?
My question is : how to move the declaration out of the two "IF's" ?
In this way I also can give it a defalut value ... in case a IF fails.
If I write this line out of the two "IF's"
String::Utf8Value szQMN ("") ;
... then I get the error :
cannot convert argument 1 from 'const char [1]' to 'v8::Handle<v8::Value>'
Any ideas?

This means to me that the sentence marked (A) is a definition at the same time as an assignement, right?
Technically it is a constructor call that creates a variable and initializes it.
Also note that automatic variables exist only until the end of the scope (usually a block inside {} brackets). That is why your second code example does not compile.
if (condition)
{
int x = 5;
}
x = 6; // error, x does not exist anymore
My question is : how to move the declaration out of the two "IF's"?
String::Utf8Value szQMN ("");
This is a constructor call of the class String::Utf8Value class. From the error message it takes a parameter of type v8::Handle<v8::Value>. Without knowing what this is I cannot give you an answer how to call it. You wanted to pass "" which is of type const char* or const char[1] and the compiler is telling you that it does not take that parameter.
Edit:
From the link that DeepBlackDwarf provided in the comment, this is how you create a Utf8Value from a string:
std::string something("hello world");
Handle<Value> something_else = String::New( something.c_str() );
So in your case you would do:
String::Utf8Value szQMN (String::New(""));

the definition in the IF's loop is only works in this loop.
So in the (B) sentence,the definition has already been expired.
If you need to use the var both in the IF's loop and outside,you can declare a global variability by this sentence :
extern String::Utf8Value szQMN( args[0]->ToString() ) ;

Related

Checking the size of a user defined string litteral at compile time in C++11

I'm trying to restrict the use of some user defined litteral for string to a given length
Carte operator"" _C (const char* str, std::size_t sz) {
if (sz != 2)
throw runtime_error("Wrong size of string");
return from_string(str);
}
This works perfectly except that since litteral is known at compile time, the size test could be done at that time as well. However the I can't use a static assert here
jeu.cpp:105:17: error: static_assert expression is not an integral constant expression
static_assert(sz == 2, "Wrong size of string");
^~~~~~~
jeu.cpp:105:17: note: read of non-const variable 'sz' is not allowed in a constant expression
jeu.cpp:104:51: note: declared here
Is there a way to check the size of user defined string litteral at compile time in c++11 ?
If not, is it possible with more recent standard of c++ ?
use sizeof(test) to get length.. then you can use static_assert
const char test[] = "blablalba";
static_assert (sizeof(test) == 10);

error: type name requires a specifier or qualifier

if (i==15)
{
(f/(10(^)13)) ==34 || (f/(10(^)13)) ==37;
printf("AMEX \n");
}
I couldn't find what's wrong here. I get the error of "type name requires a specifier or qualifier" and "Expected expression"
The priority of == is greater than ^ but I've put ^ between brackets so it shall execute first.
Their are several problems in your code:
First 10(^)13 cannot be written, you should have write 10^13
The ^ operator is the bitwise xor.
So 10^13 will be evaluated to 7 (1010b xor 1101b -> 0111b), it's not what you want.
You forgot the if in your test (and the ; will cause you some trouble if you do not removed it when you add the if).
So if f is a 64 bits integer, the correct syntax of what you want is:
#define CARD_TYPE_POSITION 10000000000000
if (i==15)
{
if (((f/CARD_TYPE_POSITION) == 34) || ((f/CARD_TYPE_POSITION) == 37))
printf("AMEX \n");
}
You can also compute the card type once:
#define CARD_TYPE_POSITION 10000000000000
if (i==15)
{
int card_type = f / CARD_TYPE_POSITION;
if ((card_type == 34) || (card_type == 37))
printf("AMEX \n");
}

Initializing a C++11 string with {}

What is the difference between initializing a string with:
std::string testString = "Test";
and
std::string testString{"Test"};
Is this only syntactic sugar thing or there actually are some performance related differences?
The {} initialization syntax is known as the uniform initialization syntax, it has a few key differences, but in your code as is they both do the same thing - construct a std::string object from the string literal "Test"
Initializing an object with an assignment is essentially the same as putting the right hand side in parentheses and constructing the object. For example the below two are the same
T obj = a;
T obj(a);
So you should be asking yourself, what is the difference between constructing a string object the following two ways
std::string{"Test"};
std::string("Test");
And the answer is that both the constructions above are the same and call the same constructor for std::string
For more on uniform initialization see https://softwareengineering.stackexchange.com/questions/133688/is-c11-uniform-initialization-a-replacement-for-the-old-style-syntax
There is no difference in this particular case. But try
std::string s1(1, '0'); // calls string(size_type , char )
std::string s2{1, '0'}; // calls string(std::initializer_list<char> )
assert(s1.length() == 1 && s1[0] == '0');
assert(s2.length() == 2 && s2[0] == '\x1');
or with std::vector
std::vector<int> v1(1); // calls vector(size_type )
std::vector<int> v2{1}; // calls vector(std::initializer_list<int> )
assert(v1.size() == 1 && v1[0] == 0);
assert(v2.size() == 1 && v2[0] == 1);
There is no difference between them.
First declaration is preferred in most projects due to the syntax highlighting.
I found a clear answer in Herb Sutter
https://herbsutter.com/2013/05/09/gotw-1-solution/

error C2440: '=' : cannot convert from 'const char *' to 'char *'

I've spent many hours on here looking for help on what is apparently a common error but none that I've seen seems to fit my case.
I am migrating a old out sourced program that was written in Visual Studio 6 C++ to Visual Studio 2012 and fortunately for me as I'm not a C++ programmer (just a lowly VB and C# developer). The migration wizard and the internet have been a great help in helping me find and correct code that the wizard can't handle.
In this code block which I believe is doing nothing more than creating a directory
int CreateAllDirectories(const char* pszDir)
{
char* pszLastSlash;
char cTmp;
if( _access( pszDir, 0 ) != -1 ) {
// it already exists
return 0;
}
pszLastSlash = strrchr( pszDir, '\\' );
if ( pszLastSlash ) {
cTmp = *pszLastSlash;
*pszLastSlash = '\0';
// try again with one less dir
CreateAllDirectories( pszDir );
*pszLastSlash = cTmp;
}
if ( _mkdir( pszDir ) == -1 ) {
return -1;
}
return 0;
}
an error generates when the results of strrchr( pszDir, '\' ) are assigned to the variable pszLastSlash. From the rest of this code it looks like pszLastSlash = strrchr( pszDir, '\' ); is a valid expression.
Is the issue with the double backslash which to me looks like and escape sequence.
Maybe in this line...
pszLastSlash = strrchr( pszDir, '\\' );
pszLastSlash is not constant but pszDir is constant. There are two defs for strrchr() (see http://www.cplusplus.com/reference/cstring/strchr/)...
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
Because you input a constant char *, it will try to use the def that returns a const char*, but you're assigning it to a non-const char*. I think that is what is generating your error.
Because pszDir is const, the pointer returned to you is const because you shouldn't be modifying the area of memory pointed to by pszDir.
If you have allocated pszDir yourself, and you know it is safe to modify, your could relax your const contraint in the function def? I.e.,
int CreateAllDirectories(char* pszDir)
But, only do this is pszDir is a string that you own and can modify :)
I just noticed in the C++ reference page that...
In C, this function is only declared as:
char * strchr ( const char *, int );
So, if you previously used C, then that would explain why you see the error now.
Since this line
*pszLastSlash = '\0';
is modifying the buffer passed into your function, you must not promise your caller that you won't modify the buffer. Therefore
int CreateAllDirectories(char* pszDir);
is the correct signature
You can try putting new in the middle of
pszLastSlash = strrchr( pszDir, '\' );
So, it will be
:pszLastSlash = new strrchr( pszDir, '\' );

[Perl]: Not a CODE reference ... my 1st script

i am getting the following error when i am trying to run my 1st Perl script:
[id=0 # 0] : IP address "3.3.3.3" corresponds to device "core".
Thread 1 terminated abnormally: Not a CODE reference at ./dev_ithread.pl line 23.
[id=0 # 1] : IP address "5.5.5.5" corresponds to device "border".
Thread 2 terminated abnormally: Not a CODE reference at ./dev_ithread.pl line 23.
and here is what i have written so far
#!/usr/bin/perl
use strict ;
use warnings ;
use diagnostics ;
use threads ;
use Config ;
$Config{useithreads} || die("\n---> Please recompile Perl with \<ithreads\> included. \n") ;
# IP parameterization of network elements.
my %device_ip = (
"core" => "3.3.3.3",
"border" => "5.5.5.5",
) ;
# Initialize devices' pool of threads.
my $index = 0 ;
my #device_thread = () ;
while( my ($key, $value) = each %device_ip )
{
push( #device_thread, threads->new(\&thread_job($key, $device_ip{$key}, $index))->join ) ; $index = $index+1 ;
}
# Worker thread subroutine.
sub thread_job
{
my ($device, $ip, $index) = #_ ;
my $ithread = threads->tid() ;
print "[id=$ithread # $index] : IP address \"$ip\" corresponds to device \"$device\". \n" ;
}
i would be thankful, if someone could help me overcome this problem.
thank you.
The first argument to threads->new() must be a code reference or the name of a function. You are executing the function and try to take a code reference of the result (which is most likely a true value since that is what print returns), hence the error. I guess your call should be like this:
threads->new(\&thread_job, $key, $device_ip{$key}, $index)->join
\&thread_job($key, $device_ip{$key}, $index) doesn't do what you think it does: it runs thread_job(...) immediately, then produces a reference to its result. threads->new then tries to execute that reference inside the new thread, which doesn't work because it's not a reference to a sub.
You probably want to say sub { thread_job($key, $device_ip{$key}, $index) } instead. (Or #musiKk's version.)

Resources