Next: , Previous: , Up: C   [Index]


C statements

Pragmas

Ctalk recognizes GCC, G++, and C99 pragmas.

Pragmas that apply to floating point operations and code generation are ignored and elided, unless the ‘--keeppragmas’ command line option is given. See Invoking.

Inclusion of a file that contains G++ pragmas causes the preprocessor to issue a warning if the ‘-v’ option is given, and ctalk ignores the file. See Invoking.

Here is the effect of the GCC and C99 pragmas.

#pragma interface
#pragma implementation

The include file is not processed.

#pragma GCC dependency file

Issues a warning if the source file is more recent than file.

#pragma GCC poison identifier ...

ctalk issues an error and discontinues processing if the source file contains an identifier given as an argument.

#pragma GCC system header

The ctalk preprocessor processes all input files in the same manner and ignores this pragma.

#pragma GCC pack
#pragma STDC FP_CONTRACT
#pragma STDC FENV_ACCESS
#pragma STDC CX_LIMITED_RANGE

ctalk ignores and elides these pragmas, which apply to floating point and code generation options, unless the ‘--keeppragmas’ option is used. See Invoking.

C Expressions

In version 0.66 2021-02-02, you can use simple constant expressions as receivers, as in this example.

printf ("%s", "/home/users/joe" subString 1, self length - 1);

Warning - This use of self is experimental in version 0.66 2021-02-02 and should be used with caution.

You can use a C constant in place of any receiver whose class corresponds to a basic C data type. These classes include Character, String, Float, Integer, and LongInteger.

Expressions like the following work.

if (99 == myInt)
 ...

if ('c' == myInt asCharacter)
 ...

if (3.1416 == pi)
 ...

The following code examples are equivalent.

myString = "This is a string.";
printf ("%d\n", myString length);

and,

printf ("%d\n", "This is a string" length);

However, if you try to use a C variable on the left side of a method that overloads a C operator, the expression might simply be interpreted as C code, as in this example.

  String new progName;

  progName = "myprog";

  if (argv[0] == progName) {
    ...
  }

This is because Ctalk does not interpret argv[0] as a receiver object, and then interprets == as a C operator.

Objects in Function Parameters

Programs cannot, at this time, use objects as parameters to C functions. If you need to use an object as a parameter, you need to use a method instead of a function, or translate the object’s value to C. See Translating.

Objects in Function Arguments

You can use of Ctalk expressions as C function arguments, but the values should be treated as read-only, as in this example.

Integer new myIndex;
char buf[255];

myIndex = 0;

/*
 *   This statement works correctly. 
 */
sprintf (buf, "%d", __ctalk_to_c_int (myIndex));

/*
 *   This statement does not work correctly.
 */
sscanf (myString, "%s %s", mySubString1, mySubString2);

If you need to read a string into objects, try readFormat (class String) instead.

If you receive an Unimplemented C type warning, it means that Ctalk does not implement a class that corresponds to the data type. In these cases, you can generally assign the C variable to an instance of class Symbol, and use that as the argument to a function.

The Classes that implement C data types are described in the next section.

C Data Type Classes

These classes correspond to the basic C types.

Array

char **

Character

char

Float

float and double

Integer

int and long int

LongInteger

long long int

String

char *

Typedefs in Function Arguments

Ctalk resolves many of the derived types defined in C99, as well as incomplete types; however, variables that are of derived types can still cause unpredictable results, if the variable is of an unusual or complex type.

If you encounter a case where a derived type confuses the parser or run-time library, the workaround is to declare the type as an equivalent C type. For example, if a variable is of type time_t, you could equivalently declare it as type long long int.

C Functions in Complex Expressions

You can use C functions in complex expressions within conditionals, as in this example.

int int_fn1 (void) {
  return 10;
}

char *add_int_fn_as_string (int a, int b, int c) {
  static char buf[30];
  sprintf (buf, "%d", a + b + c);
  return buf;
}

int main () {

  String new myString1;

  if ((myString1 = add_int_fn_as_string (int_fn1 (), 20, 30)) != "60")
    exit(1);
    
  printf ("%s\n", myString1);

}

As long as your function returns one of the C data types int, char, char *, or double, Ctalk can translate the function output to an object, as well as call the function at run time using a method call.

If you try to use a C function that returns a complex or derived type, Ctalk prints a warning and uses Integer as the default return class. In these cases, you should consider writing a method instead.

Note: When you use functions in complex expressions, the function’s arguments must also be C variables or expressions. If you want to use objects as the arguments to a function, then you must perform the object-to-C translation manually.

Debugging

Object Inspectors

Ctalk provides a basic set of methods that can inspect and print the contents of objects.

The inspect method in Object class is an interactive utility that lets you examine a program’s objects as the program is running.

To inspect an object, simply send it the message, inspect - it’s a shortcut for the inspect method in ObjectInspector class, which a program can also call directly.


String new globalString;

int main () {
  Integer new i;

  globalString = "global string";

  i inspect;
}

In either case, the program stops execution when it reaches the inspect method, and presents a prompt where you can type commands.

Here’s a transcript of a brief inspector session.


$ ./inspect 
> p
p
name:       i
class:      Integer (0x48bf4958)
superclass: Magnitude (0x48bf29f0)
value:      (null) (Integer)

> p g globalString
p g globalString
name:       globalString
class:      String (0x48cce8d0)
superclass: Character (0x48c8acc0)
value:      global string (String)

> c
c
$ 

At the inspector prompt, ‘> ’, the command ‘p’ prints the inspector’s receiver object, and ‘p g globalString’ prints the named global object, globalString. The ‘c’ command exits the inspector and continues running the program.

There are several commands that the inspector recognizes. Typing ‘?,’ ‘h,’ or ‘help’ at the prompt displays a list of them.

The inspector uses the method formatObject to print the contents of individual objects.

If you want to print a formatted object directly, without stopping the program, Ctalk also has the method dump in Object class, which simply calls formatObject with its receiver object to print the object and then returns so the program can continue running.

Using gdb for Debugging

The GNU gdb debugger allows you to trace through Ctalk applications as well as the compiler and the run-time libraries, at the level of Ctalk’s source code.

In order to debug Ctalk programs with gdb, the source must be compatible with the debugger; that means that you can debug Ctalk programs using the intermediate C code to get source level debugging within Ctalk apps.

You can also examine the contents of objects and their run-time environment with the inspect method (in Object class), which doesn’t use line number information. See Object_inspect. There’s a tutorial on using object inspectors in the ctalktools Texinfo manual, and yet more information in the inspect.3ctalk manual page.

The ‘-P’ command line option disables line numbering. You can then debug the intermediate output, which is normal C that gdb can interpret correctly.

This means that method line numbers are calculated from the start of all of the input, which includes all other classes and header files. So when you give the ‘-P’ option to Ctalk, it reports the line if possible, although without line number information, the compiler can’t track line numbers of preprocessor output; like for example, by adjusting line numbers after including a file with the ‘#include’ directive.

The ctdb command builds Ctalk programs with the correct arguments for debugging. Then you can use gdb to debug the program.

$ ctdb -k myprog.c -o myprog

If you need to debug either ctalk or the libctalk library, then you need to build and install Ctalk without optimization. You can do that by adding the ‘--without-optimization’ option to configure when building Ctalk. Compiler optimization often removes lines of code (and variables) from the binary, so the output often doesn’t correspond to the source code. Also, it often helps to add the ‘--without-inline-functions’ option to configure.


$ ./configure --without-inline-functions --without-optimization

Then build and install Ctalk with make and make install.

Ctalk also provides other build options. Typing

$ ./configure --help

at the shell prompt prints a list of them.

Ctalk is compatible at the machine code level with C programs. That means you use most of gdb's functions, like peek into a running program and examine core dumps. The gdb documentation describes the debugger’s extensive set of options.


Next: , Previous: , Up: C   [Index]