Is this ternary conditional ?: correct (Objective) C syntax? - objective-c

I didn't think this was possible but apparently in Objective C it is allowed:
int a = b ?: c;
So you see what they're doing here, they're leaving out the second part of the ternary expression, such that if b is nonzero, b is used as the second part.
It's clever but as far as I know this is against K&R C, and probably ANSI C.
If not, I've been missing out of a terribly clever syntax trick for years...alas!
Update:
It is gcc.

From http://en.wikipedia.org/wiki/%3F%3A
A GNU extension to C allows omitting the second operand, and using implicitly the first operand as the second also:
a = x ? : y;
The expression is equivalent to
a = x ? x : y;
except that if x is an expression, it is evaluated only once. The difference is significant if evaluating the expression has side effects.

This behaviour is defined for both gcc and clang. If you're building macOS or iOS code, there's no reason not to use it.
I would not use it in portable code, though, without carefully considering it.

$ cat > foo.c
#include <stdio.h>
int main(int argc, char **argv)
{
int b = 2;
int c = 4;
int a = b ?: c;
printf("a: %d\n", a);
return 0;
}
$ gcc -pedantic -Wall foo.c
foo.c: In function ‘main’:
foo.c:7: warning: ISO C forbids omitting the middle term of a ?: expression
So no, it's not allowed. What gcc emits in this case does this:
$ ./a.out
a: 2
So the undefined behaviour is doing what you say in your question, even though you don't want to rely on that.

This is a GNU C extension. Check you compiler settings (look for C flavor). Not sure if it's part of Clang, the only information I could get is in this page:
Introduction
This document describes the language extensions provided by Clang. In addition to the language extensions listed here, Clang aims to support a broad range of GCC extensions. Please see the GCC manual for more information on these extensions.

Related

Formatting in Raku

I have written a function that outputs a double, upto 25 decimal
places. I am trying to print it as a formatted output from Raku.
However, the output is incorrect and truncated.
See MWE:
my $var = 0.8144262510988963255087469;
say sprintf("The variable value is: %.25f", $var)
The above code gives The variable value is: 0.8144262510988963000000000 which is not what is expected.
Also, this seems weird:
my $var = 0.8144262510988963255087469;
say $var.Str.chars; # 29 wrong, expected 27
I tested the same in C:
#include <stdio.h>
int main() {
double var = 0.8144262510988963255087469;
printf("The variable value is: %.25lf \n", var);
return 0;
}
However, it works fine. Given the identical nature of sprintf and printf, I expected this C example to work in Raku too. Seems like %lf is not supported.
So is there a workaround to fix this?
I think this is actually a bug in how Rat literals are created. Or at least as WAT :-).
I actually sort of expect 0.8144262510988963255087469 to either give a compile time warning, or create a Num, as it exceeds the standard precision of a Rat:
raku -e 'say 0.8144262510988963255087469'
0.814426251098896400086204416
Note that these are not the same.
There is fortunately an easy workaround, by creating a FatRat
$ raku -e 'say 0.8144262510988963255087469.FatRat'
0.8144262510988963255087469
FWIW, I think this is worthy of creating an issue
From your question:
I have written a function that outputs a double, upto 25 decimal places.
From google:
Double precision numbers are accurate up to sixteen decimal places
From the raku docs :
When constructing a Rat (i.e. when it is not a result of some mathematical expression), however, a larger denominator can be used
so if you go
my $v = 0.8144262510988963255087469;
say $v.raku;
#<8144262510988963255087469/10000000000000000000000000>
it works.
However, do a mathematical expression such as
my $b = $a/10000000000000000000000000;
and you get the Rat => Num degradation applied unless you explicitly declare FatRats. I visualise this as the math operation placing the result in a Num register in the CPU.
The docs also mention that .say and .put may be less faithful than .raku, presumably because they use math operations (or coercion) internally.
Sorry to be the bearer of bad news, but 10**25 > 2 **64, but what you report as an issue is correct & (fairly) well documented behaviour given the constraints of double precision IEEE P754.

Bison Syntax Error easy file

i'm trying to run this .y file
%{
#include <stdlib.h>
#include <stdio.h>
int yylex();
int yyerror();
%}
%start BEGIN
%%
BEGIN: 'a' | BEGIN 'a'
%%
int yylex(){
return getchar();
}
int yyerror(char* s){
fprintf(stderr, "*** ERROR: %s\n", s);
return 0;
}
int main(int argn, char **argv){
yyparse();
return 0;
}
It's a simple program in bison, the syntax seems to me correct, but always get the Syntax error problem ...
Thanks for your help.
The lexer function yylex needs to return 0 to indicate the end of the input. However, your implementation simply passes through the value returned by getchar, which will be EOF (normally -1).
Also, your input is almost certain to include a newline character, which will also be passed through to the parser.
Since the parser recognizes neither \n nor EOF, it produces an error when it receives one of them.
At a minimum, you would need to modify yylex to correctly respond to end of input:
int yylex(void) {
int ch = getchar();
return (ch == EOF) ? 0 : ch;
}
But you will still have to deal with newline charactets, either by handling them in your lexer (possibly ignoring them or possibly returning an end of input imdication), or by handling them in your grammar.
Note that bison/yacc-generated parsers always parse the entire input stream, not just the longest sequence satisfying the grammar. That can be adjusted with some work -- see the documentation for the YYACCEPT special action -- but the standard behaviour is usually what is desired when parsing.
By the way, please use standard style conventions in your bison/yacc grammars, in order to avoid problems and in order to avoid confusing readers. Normally we reserve UPPER_CASE for terminal symbols, since those are also used as compile-time constants in the lexer. Non-terminals are usually written in lower_case although some prefer to use CamelCase. For the terminals, you need to avoid the use of names reserved by the standard library (such as EOF) or by (f)lex (BEGIN) or bison/yacc (END). There are lists of reserved names in the manuals.

How to disable a specific warning in g++

First of all I don't know why "g++ -std=c++0x -Wall" would give me warning: invalid suffix on literal; C++11 requires a space between literal and string macro [-Wliteral-suffix] on the following program:
#include <iostream>
#define BEGIN "<b>"
#define END "</b>"
#pragma GCC diagnostic ignored "-Wliteral-suffix"
int main()
{
std::cout << "hello " BEGIN"world"END "\n";
}
Second, I followed gcc doc to ignore "-Wliteral-suffix" but still got the warning. How do I suppress the warning? And why does the compiler warn in the first place?
Ok, to summarize: the failure to suppress the warning is a known gcc bug (gcc.gnu.org/bugzilla/show_bug.cgi?id=61653). Since you cannot (and really, should not) suppress the warning, the easiest fix is to put a space between the literal and the #define string. You can safely do this; it won't change the output text.
The reason this is no longer allowed is because characters directly after a literal string are treated as user-defined literals, which is a new feature in C++11. User-defined literals are considered to be part of the same single token as the literal they modify, thus END will not be subject to replacement by the earlier #define.

ATI OpenCL printf extension issue with char* argument passed to a function

I use OpenCL on an ATI card with the printf extension enabled. I've written a function to print out variables:
void printVar(constant char* name, float var)
{
printf("%s: %f\r\n", name, var);
}
This code works as expected when compiled as plain C, but if i invoke it in OpenCL with
printVar("foo", 0.123);
the result is always some random char followed by 0.123 instead of "foo: 0.123". I guess the compiler has problems with recognizing the char* string, is there a workaround or a fix so i can get the function working?
As I mentioned in my comment I also get the same behavior, however I can suggest a simple workaround for the use case you showed, I.e. when the string is known at compile time we could just use a define statement instead:
#define PRINTVAR(N,X) (printf(N ": %f\r\n", X))

Objective-c main routine, what is: int argc, const char * argv[]

What are the arguments passed into the main method of a command-line program:
int main(int argc, const char * argv[])
what is the first int mean?
And what is the 2nd parameter, is that an array of chars?
How would one use these?
Also, what practical use is a command-line project type, other than using it to learn obj-c i.e. to practise.
argc means "argument count". It signifies how many arguments are being passed into the executable.
argv means "argument values". It is a pointer to an array of characters. Or to think about it in another way, it is an array of C strings (since C strings are just arrays of characters).
So if you have a program "foo" and execute it like this:
foo -bar baz -theAnswer 42
Then in your main() function, argc will be 5, and argv will be:
argv[0] = "/full/path/to/foo";
argv[1] = "-bar";
argv[2] = "baz";
argv[3] = "-theAnswer";
argv[4] = "42";
The parameters to main() are a unix convention for accessing the arguments given on the command line when your program is executed. In a Cocoa app, you can access them the plain old C way, or you can use NSProcessInfo's -arguments method to get them in an NSArray of NSString objects, or use NSUserDefaults to get them as values in a dictionary.
Just to add to the other answers - Objective-C targets both OS X and iOS. And while there is not much value in iOS command line applications, the shell on OS X is still widely used and there are lot of people writing command line tools.
That main is from C and not specific to objective-c. Argc gives you the number of command line arguments passed to your C program. Argv is an array of C strings and contains the command line arguments.
You would use them and the command-line project any time you wanted to write a command line tool or a program you interact with from the command line.
As wikipedia (and any other source says):
int main(void)
int main(int argc, char *argv[])
The parameters argc, argument count, and argv, argument vector, respectively give the number and value of the program's command-line arguments. The names of argc and argv may be any valid identifier in C, but it is common convention to use these names. In C++, the names are to be taken literally, and the "void" in the parameter list is to be omitted, if strict conformance is desired. Other platform-dependent formats are also allowed by the C and C++ standards, except that in C++ the return type must stay int; for example, Unix (though not POSIX.1) and Microsoft Windows have a third argument giving the program's environment, otherwise accessible through getenv in stdlib.h:
int main(int argc, char **argv, char **envp)
Also, what practical use is a command-line project type, other than using it to learn obj-c i.e. to practise.
The practical use is creating a command-line tool using code from a Framework or Application that you have written. Helpers, utilities, launch agents and daemons, all of these background processes are typically implemented as command-line tools.