Cyclone (programming language): Difference between revisions
imported>Headbomb ce |
imported>AnomieBOT m Dating maintenance tags: {{Fact}} |
||
| Line 18: | Line 18: | ||
| implementations = | | implementations = | ||
| dialects = | | dialects = | ||
| influenced by = [[C (programming language)|C]] | | influenced by = [[C (programming language)|C]], [[C++]]<ref>{{Cite web|title=Cyclone for C programmers|url= https://cyclone.thelanguage.org/wiki/Cyclone%20for%20C%20Programmers/#Additions|access-date=12 October 2025|website=cyclone.thelanguage.org}}</ref> | ||
| influenced = [[Rust (programming language)|Rust]], [[Project Verona]] | | influenced = [[Rust (programming language)|Rust]], [[Project Verona]] | ||
| programming language = | | programming language = | ||
| Line 29: | Line 29: | ||
The '''Cyclone''' [[programming language]] was intended to be a safe dialect of the [[C (programming language)|C language]].<ref>{{Cite journal |last1=Jim |first1=Trevor |last2=Morrisett |first2=J. Greg |last3=Grossman |first3=Dan |last4=Hicks |first4=Michael W. |last5=Cheney |first5=James |last6=Wang |first6=Yanling |date=2002-06-10 |title=Cyclone: A Safe Dialect of C |url=https://dl.acm.org/doi/10.5555/647057.713871 |journal=Proceedings of the General Track of the Annual Conference on USENIX Annual Technical Conference |series=ATEC '02 |location=USA |publisher=USENIX Association |pages=275–288 |isbn=978-1-880446-00-3}}</ref> It avoids [[buffer overflow]]s and other vulnerabilities that are possible in C programs by design, without losing the power and convenience of C as a tool for [[system programming]]. It is no longer supported by its original developers, with the reference tooling not supporting [[64-bit computing|64-bit platforms]]. The [[Rust (programming language)|Rust]] language is mentioned by the original developers for having integrated many of the same ideas Cyclone had.<ref>{{cite web |title=Cyclone |url=http://cyclone.thelanguage.org/ |website=cyclone.thelanguage.org |access-date=11 December 2023 |archive-date=21 May 2006 |archive-url=https://web.archive.org/web/20060521202022/http://cyclone.thelanguage.org/ |url-status=live }}</ref> | The '''Cyclone''' [[programming language]] was intended to be a safe dialect of the [[C (programming language)|C language]].<ref>{{Cite journal |last1=Jim |first1=Trevor |last2=Morrisett |first2=J. Greg |last3=Grossman |first3=Dan |last4=Hicks |first4=Michael W. |last5=Cheney |first5=James |last6=Wang |first6=Yanling |date=2002-06-10 |title=Cyclone: A Safe Dialect of C |url=https://dl.acm.org/doi/10.5555/647057.713871 |journal=Proceedings of the General Track of the Annual Conference on USENIX Annual Technical Conference |series=ATEC '02 |location=USA |publisher=USENIX Association |pages=275–288 |isbn=978-1-880446-00-3}}</ref> It avoids [[buffer overflow]]s and other vulnerabilities that are possible in C programs by design, without losing the power and convenience of C as a tool for [[system programming]]. It is no longer supported by its original developers, with the reference tooling not supporting [[64-bit computing|64-bit platforms]]. The [[Rust (programming language)|Rust]] language is mentioned by the original developers for having integrated many of the same ideas Cyclone had.<ref>{{cite web |title=Cyclone |url=http://cyclone.thelanguage.org/ |website=cyclone.thelanguage.org |access-date=11 December 2023 |archive-date=21 May 2006 |archive-url=https://web.archive.org/web/20060521202022/http://cyclone.thelanguage.org/ |url-status=live }}</ref> | ||
Cyclone development was started as a joint project of Trevor Jim from [[AT&T Labs]] Research and [[Greg Morrisett]]'s group at [[Cornell University]] in 2001. Version 1.0 was released on May 8, 2006.<ref>{{cite web |title=Cyclone |url= | Cyclone development was started as a joint project of Trevor Jim from [[AT&T Labs]] Research and [[Greg Morrisett]]'s group at [[Cornell University]] in 2001. Version 1.0 was released on May 8, 2006.<ref>{{cite web |title=Cyclone |url=https://www.cs.cornell.edu/Projects/cyclone/ |website=[[Cornell University]] |access-date=30 October 2022 |archive-date=15 October 2022 |archive-url=https://web.archive.org/web/20221015034248/https://www.cs.cornell.edu/Projects/cyclone/ |url-status=live }}</ref> | ||
==Language features== | ==Language features== | ||
Cyclone attempts to avoid some of the common pitfalls of [[C (programming language)|C]], while still maintaining its look and performance. To this end, Cyclone places the following limits on programs: | Cyclone attempts to avoid some of the common pitfalls of [[C (programming language)|C]], while still maintaining its look and performance.{{fact|date=April 2026}} To this end, Cyclone places the following limits on programs: | ||
* <code>[[Null pointer|NULL]]</code> checks are inserted to prevent [[segmentation fault]]s | * <code>[[Null pointer|NULL]]</code> checks are inserted to prevent [[segmentation fault]]s | ||
* [[Pointer arithmetic]] is limited | * [[Pointer arithmetic]] is limited | ||
| Line 48: | Line 48: | ||
* Growable regions support a form of safe manual memory management | * Growable regions support a form of safe manual memory management | ||
* [[Garbage collection (computer science)|Garbage collection]] for heap-allocated values | * [[Garbage collection (computer science)|Garbage collection]] for heap-allocated values | ||
* [[Smart pointer]]s, such as unique pointers | |||
* [[Region-based memory management]] | |||
* [[Tagged union]]s support type-varying arguments | * [[Tagged union]]s support type-varying arguments | ||
* Injections help automate the use of tagged unions for programmers | * Injections help automate the use of tagged unions for programmers | ||
* [[Polymorphism (computer science)|Polymorphism]] replaces some uses of [[void pointer|<code>void *</code>]] | * [[Polymorphism (computer science)|Polymorphism]] replaces some uses of [[void pointer|<code>void*</code>]] | ||
* | * [[Variadic function|Variadic arguments]] are implemented as fat pointers | ||
* [[Exception handling|Exceptions]] replace some uses of <code>setjmp</code> and <code>longjmp</code> | * [[Exception handling|Exceptions]] replace some uses of <code>setjmp</code> and <code>longjmp</code> | ||
* [[Namespace]]s | |||
* [[Type inference]] | |||
* [[Pattern matching]] | |||
* [[Template (C++)|Templates]], parameterized types | |||
Cyclone looks, in general, much like C, but it should be viewed as a C-like language. | Cyclone looks, in general, much like C, but it should be viewed as a C-like language. | ||
| Line 65: | Line 69: | ||
The purpose of introducing these new pointer types is to avoid common problems when using pointers. Take for instance a function, called <code>foo</code> that takes a pointer to an int: | The purpose of introducing these new pointer types is to avoid common problems when using pointers. Take for instance a function, called <code>foo</code> that takes a pointer to an int: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
int foo(int* p); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Although the person who wrote the function <code>foo</code> could have inserted <code>NULL</code> checks, let us assume that for performance reasons they did not. Calling <code>foo(NULL);</code> will result in [[undefined behavior]] (typically, although not necessarily, a [[SIGSEGV]] [[Unix signal|signal]] being sent to the application). To avoid such problems, Cyclone introduces the <code>@</code> pointer type, which can never be <code>NULL</code>. Thus, the "safe" version of <code>foo</code> would be: | Although the person who wrote the function <code>foo</code> could have inserted <code>NULL</code> checks, let us assume that for performance reasons they did not. Calling <code>foo(NULL);</code> will result in [[undefined behavior]] (typically, although not necessarily, a <code>[[SIGSEGV]]</code> [[Unix signal|signal]] being sent to the application). To avoid such problems, Cyclone introduces the <code>@</code> pointer type, which can never be <code>NULL</code>. Thus, the "safe" version of <code>foo</code> would be: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
int foo(int@ p); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
This tells the Cyclone compiler that the argument to <code>foo</code> should never be <code>NULL</code>, avoiding the aforementioned undefined behavior. The simple change of <code>*</code> to <code>@</code> saves the programmer from having to write <code>NULL</code> checks and the operating system from having to trap <code>NULL</code> pointer dereferences. This extra limit, however, can be a rather large stumbling block for most C programmers, who are used to being able to manipulate their pointers directly with arithmetic. Although this is desirable, it can lead to [[buffer overflow]]s and other "off-by-one"-style mistakes. To avoid this, the <code>?</code> pointer type is delimited by a known bound, the size of the array. Although this adds overhead due to the extra information stored about the pointer, it improves safety and security. Take for instance a simple (and naïve) <code>strlen</code> function, written in C: | This tells the Cyclone compiler that the argument to <code>foo</code> should never be <code>NULL</code>, avoiding the aforementioned undefined behavior. The simple change of <code>*</code> to <code>@</code> saves the programmer from having to write <code>NULL</code> checks and the operating system from having to trap <code>NULL</code> pointer dereferences. This extra limit, however, can be a rather large stumbling block for most C programmers, who are used to being able to manipulate their pointers directly with arithmetic. Although this is desirable, it can lead to [[buffer overflow]]s and other "off-by-one"-style mistakes. To avoid this, the <code>?</code> pointer type is delimited by a known bound, the size of the array. Although this adds overhead due to the extra information stored about the pointer, it improves safety and security. Take for instance a simple (and naïve) <code>strlen</code> function, written in C: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
int strlen(const char* s) { | |||
int i = 0; | |||
if (!s) { | |||
return 0; | return 0; | ||
} | |||
while (s[i] != '\0') { | |||
i++; | i++; | ||
} | |||
return i; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
This function assumes that the string being passed in is terminated by <code>'\0'</code>. | This function assumes that the string being passed in is terminated by <code>'\0'</code>. If this code was passed the unterminated string {{code|style=white-space:nowrap|2=c|1=char buf[6] = {'h','e','l','l','o','!'};}}, <code>strlen</code> would iterate beyond the end of the string, into memory not associated with the string. Non [[ANSI C]] functions such as such as <code>strnlen</code> seek to address such problems. | ||
The Cyclone's <code>strlen</code> is similar to the C version: | |||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
int strlen(const char? s) { | |||
int n = s.size; | |||
int | if (!s) { | ||
if (s | return 0; | ||
} | |||
for (i = 0; i < n; i++, s++) | for (int i = 0; i < n; i++, s++) { | ||
if (*s == '\0') { | |||
return i; | |||
} | |||
} | |||
return n; | return n; | ||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Here, <code>strlen</code> bounds itself by the length of the array passed to it | Here, <code>strlen</code> bounds itself by the length of the array passed to it. Each of the kinds of pointer type can be safely cast to each of the others, and arrays and strings are automatically cast to <code>?</code> by the compiler. (Casting from <code>?</code> to <code>*</code> invokes a [[bounds checking|bounds check]], and casting from <code>?</code> to <code>@</code> invokes both a <code>NULL</code> check and a bounds check. Casting from <code>*</code> to <code>?</code> results in no checks whatsoever; the resulting <code>?</code> pointer has a size of 1.) | ||
===Dangling pointers and region analysis=== | ===Dangling pointers and region analysis=== | ||
Consider the following code, in C: | Consider the following code, in C: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
char* itoa(int i) { | |||
char buf[20]; | char buf[20]; | ||
sprintf(buf,"%d",i); | sprintf(buf, "%d", i); | ||
return buf; | return buf; | ||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
The function <code>itoa</code> allocates an array of chars <code>buf</code> on the stack and returns a pointer to the start of <code>buf</code>. However, the memory used on the stack for <code>buf</code> is deallocated when the function returns, so the returned value cannot be used safely outside of the function. While [[GNU Compiler Collection]] and other compilers will warn about such code, the following will typically compile without warnings: | The function <code>itoa</code> allocates an array of chars <code>buf</code> on the stack and returns a pointer to the start of <code>buf</code>. However, the memory used on the stack for <code>buf</code> is deallocated when the function returns, so the returned value cannot be used safely outside of the function. While [[GNU Compiler Collection]] and other compilers will warn about such code, the following will typically compile without warnings: | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
char* itoa(int i) { | |||
char buf[20]; | |||
char buf[20] | sprintf(buf, "%d", i); | ||
sprintf(buf,"%d",i); | char* z = buf; | ||
z = buf; | |||
return z; | return z; | ||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
GNU Compiler Collection can produce warnings for such code as a side-effect of option {{code|-O2}} or {{code|-O3}}, but there are no guarantees that all such errors will be detected. | GNU Compiler Collection can produce warnings for such code as a side-effect of option {{code|-O2}} or {{code|-O3}}, but there are no guarantees that all such errors will be detected. | ||
Cyclone does regional analysis of each segment of code, preventing dangling pointers, such as the one returned from this version of <code>itoa</code>. All of the local variables in a given scope are considered to be part of the same region, separate from the heap or any other local region. Thus, when analyzing <code>itoa</code>, the Cyclone compiler would see that <code>z</code> is a pointer into the local stack, and would report an error. | Cyclone does regional analysis of each segment of code, preventing dangling pointers, such as the one returned from this version of <code>itoa</code>. All of the local variables in a given scope are considered to be part of the same region, separate from the heap or any other local region. Thus, when analyzing <code>itoa</code>, the Cyclone compiler would see that <code>z</code> is a pointer into the local stack, and would report an error. | ||
===Fat pointers=== | |||
A [[fat pointer]] is used for allowing pointer arithmetic. Fat pointers must be declared with <code>@fat</code>. For example, <code>argv</code> is often declared as type <code>char**</code> (a pointer to a pointer to a character), or alternatively thought of as <code>char*[]</code> (pointer to an array of characters). In Cyclone, this is instead expressed as <code>char*@fat*@fat</code> (a fat pointer to a fat pointer to characters). | |||
Cyclone instead allows <code>?</code> to represent <code>*@fat</code>. Thus, the two declarations are equivalent: | |||
<syntaxhighlight lang="cpp"> | |||
int main(int argc, char?? argv); | |||
// equivalent to the more verbose declaration | |||
int main(int argc, char*@fat*@fat argv); | |||
</syntaxhighlight> | |||
===Parameterized types=== | |||
Similar to [[Templates (C++)|templates in C++]], Cyclone has a form of [[generic programming]]. | |||
<syntaxhighlight lang="cpp"> | |||
typedef struct LinkedList<`a> { | |||
`a head; | |||
struct LinkedList<`a>* next; | |||
} LinkedList<`a>; | |||
// ... | |||
LinkedList<int>* ll = new LinkedList{1, new LinkedList{2, null}}; | |||
</syntaxhighlight> | |||
An "abstract" type can be used, that encapsulates the implementation type but ensures the definition does not leak to the client. | |||
<syntaxhighlight lang="csharp"> | |||
abstract struct Queue<`a> { | |||
LinkedList<`a> front; | |||
LinkedList<`a> rear; | |||
}; | |||
extern struct Queue<`a>; | |||
</syntaxhighlight> | |||
=== Namespaces === | |||
[[Namespace]]s exist in Cyclone, similar to C++. Namespaces are used to avoid name clashes in code, and follow the <code>::</code> notation as in C++. Namespaces can be nested. | |||
<syntaxhighlight lang="cpp"> | |||
namespace foo { | |||
int x; | |||
int f() { | |||
return x; | |||
} | |||
} | |||
namespace bar { | |||
using foo { | |||
int g() { | |||
return f(); | |||
} | |||
} | |||
int h() { | |||
return foo::f(); | |||
} | |||
} | |||
</syntaxhighlight> | |||
=== Pattern matching === | |||
Pattern-matching can be accomplished in Cyclone like so: | |||
<syntaxhighlight lang="cpp"> | |||
int g(int a, int b) { | |||
switch ($(a, b - 1)) { | |||
case $(0, y) && y > 1: | |||
return 1; | |||
case $(3, y) && f(x + y) == 7: | |||
return 2; | |||
case $(4, 72): | |||
return 3; | |||
default: | |||
return 4; | |||
} | |||
} | |||
</syntaxhighlight> | |||
A <code>let</code> declaration is used to match a pattern and expression. | |||
<syntaxhighlight lang="cpp"> | |||
typedef struct Pair { | |||
int x; | |||
int y; | |||
} Pair; | |||
void f(Pair p) { | |||
let Pair(first, second) = p; | |||
// equivalent to: | |||
// int first = p.x; | |||
// int second = p.y; | |||
// ... | |||
} | |||
</syntaxhighlight> | |||
=== Type inference === | |||
In Cyclone, rather than using <code>auto</code> like [[C (programming language)|C]] and [[C++]] or <code>var</code> in [[Java (programming language)|Java]] and [[C Sharp (programming language)|C#]], Cyclone instead uses <code>_</code> (an underscore) to denote a type-inferred variable. | |||
<syntaxhighlight lang="cpp"> | |||
_ x = (SomeType*)malloc(sizeof(SomeType)); | |||
// instead of: | |||
SomeType x = (SomeType*)malloc(sizeof(SomeType)); | |||
_ myNumber = 100; // inferred to int | |||
</syntaxhighlight> | |||
=== Exceptions === | |||
Cyclone features [[Exception handling (programming)|exceptions]]. An uncaught exception will halt the program. Like Java, Cyclone features a [[null pointer exception]], called <code>Null_Exception</code>. | |||
<syntaxhighlight lang="cpp"> | |||
typedef FILE File; | |||
File* f = fopen("/etc/passwd", "r"); | |||
try { | |||
int code = getc((File* @notnull)f); | |||
} catch { | |||
case &Null_Exception: | |||
printf("Error: can't open /etc/passwd\n"); | |||
return 1; | |||
case &Invalid_argument(s): | |||
printf("Error: invalid argument: %s\n", s); | |||
return 1; | |||
} | |||
</syntaxhighlight> | |||
One can also manually throw exceptions: | |||
<syntaxhighlight lang="cpp"> | |||
throw new Null_Exception("This is a null exception"); | |||
</syntaxhighlight> | |||
==See also== | ==See also== | ||
Latest revision as of 14:58, 6 April 2026
TemplateStyles' src attribute must not be empty.
This article includes a list of general references, but it remains largely unverified because it lacks sufficient corresponding inline citations. (August 2015) |
Template:Infobox programming language The Cyclone programming language was intended to be a safe dialect of the C language.[1] It avoids buffer overflows and other vulnerabilities that are possible in C programs by design, without losing the power and convenience of C as a tool for system programming. It is no longer supported by its original developers, with the reference tooling not supporting 64-bit platforms. The Rust language is mentioned by the original developers for having integrated many of the same ideas Cyclone had.[2]
Cyclone development was started as a joint project of Trevor Jim from AT&T Labs Research and Greg Morrisett's group at Cornell University in 2001. Version 1.0 was released on May 8, 2006.[3]
Language features
Cyclone attempts to avoid some of the common pitfalls of C, while still maintaining its look and performance.[citation needed] To this end, Cyclone places the following limits on programs:
NULLchecks are inserted to prevent segmentation faults- Pointer arithmetic is limited
- Pointers must be initialized before use (this is enforced by definite assignment analysis)
- Dangling pointers are prevented through region analysis and limits on
free() - Only "safe" casts and unions are allowed
gotointo scopes is disallowedswitchlabels in different scopes are disallowed- Pointer-returning functions must execute
return setjmpandlongjmpare not supported
To maintain the tool set that C programmers are used to, Cyclone provides the following extensions:
- Never-
NULLpointers do not requireNULLchecks - "Fat" pointers support pointer arithmetic with run-time bounds checking
- Growable regions support a form of safe manual memory management
- Garbage collection for heap-allocated values
- Smart pointers, such as unique pointers
- Region-based memory management
- Tagged unions support type-varying arguments
- Injections help automate the use of tagged unions for programmers
- Polymorphism replaces some uses of
void* - Variadic arguments are implemented as fat pointers
- Exceptions replace some uses of
setjmpandlongjmp - Namespaces
- Type inference
- Pattern matching
- Templates, parameterized types
Cyclone looks, in general, much like C, but it should be viewed as a C-like language.
Pointer types
Cyclone implements three kinds of pointer:
*(the normal type)@(the never-NULLpointer), and?(the only type with pointer arithmetic allowed, "fat" pointers).
The purpose of introducing these new pointer types is to avoid common problems when using pointers. Take for instance a function, called foo that takes a pointer to an int:
int foo(int* p);
Although the person who wrote the function foo could have inserted NULL checks, let us assume that for performance reasons they did not. Calling foo(NULL); will result in undefined behavior (typically, although not necessarily, a SIGSEGV signal being sent to the application). To avoid such problems, Cyclone introduces the @ pointer type, which can never be NULL. Thus, the "safe" version of foo would be:
int foo(int@ p);
This tells the Cyclone compiler that the argument to foo should never be NULL, avoiding the aforementioned undefined behavior. The simple change of * to @ saves the programmer from having to write NULL checks and the operating system from having to trap NULL pointer dereferences. This extra limit, however, can be a rather large stumbling block for most C programmers, who are used to being able to manipulate their pointers directly with arithmetic. Although this is desirable, it can lead to buffer overflows and other "off-by-one"-style mistakes. To avoid this, the ? pointer type is delimited by a known bound, the size of the array. Although this adds overhead due to the extra information stored about the pointer, it improves safety and security. Take for instance a simple (and naïve) strlen function, written in C:
int strlen(const char* s) {
int i = 0;
if (!s) {
return 0;
}
while (s[i] != '\0') {
i++;
}
return i;
}
This function assumes that the string being passed in is terminated by '\0'. If this code was passed the unterminated string char buf[6] = {'h','e','l','l','o','!'};, strlen would iterate beyond the end of the string, into memory not associated with the string. Non ANSI C functions such as such as strnlen seek to address such problems.
The Cyclone's strlen is similar to the C version:
int strlen(const char? s) {
int n = s.size;
if (!s) {
return 0;
}
for (int i = 0; i < n; i++, s++) {
if (*s == '\0') {
return i;
}
}
return n;
}
Here, strlen bounds itself by the length of the array passed to it. Each of the kinds of pointer type can be safely cast to each of the others, and arrays and strings are automatically cast to ? by the compiler. (Casting from ? to * invokes a bounds check, and casting from ? to @ invokes both a NULL check and a bounds check. Casting from * to ? results in no checks whatsoever; the resulting ? pointer has a size of 1.)
Dangling pointers and region analysis
Consider the following code, in C:
char* itoa(int i) {
char buf[20];
sprintf(buf, "%d", i);
return buf;
}
The function itoa allocates an array of chars buf on the stack and returns a pointer to the start of buf. However, the memory used on the stack for buf is deallocated when the function returns, so the returned value cannot be used safely outside of the function. While GNU Compiler Collection and other compilers will warn about such code, the following will typically compile without warnings:
char* itoa(int i) {
char buf[20];
sprintf(buf, "%d", i);
char* z = buf;
return z;
}
GNU Compiler Collection can produce warnings for such code as a side-effect of option -O2 or -O3, but there are no guarantees that all such errors will be detected.
Cyclone does regional analysis of each segment of code, preventing dangling pointers, such as the one returned from this version of itoa. All of the local variables in a given scope are considered to be part of the same region, separate from the heap or any other local region. Thus, when analyzing itoa, the Cyclone compiler would see that z is a pointer into the local stack, and would report an error.
Fat pointers
A fat pointer is used for allowing pointer arithmetic. Fat pointers must be declared with @fat. For example, argv is often declared as type char** (a pointer to a pointer to a character), or alternatively thought of as char*[] (pointer to an array of characters). In Cyclone, this is instead expressed as char*@fat*@fat (a fat pointer to a fat pointer to characters).
Cyclone instead allows ? to represent *@fat. Thus, the two declarations are equivalent:
int main(int argc, char?? argv);
// equivalent to the more verbose declaration
int main(int argc, char*@fat*@fat argv);
Parameterized types
Similar to templates in C++, Cyclone has a form of generic programming.
typedef struct LinkedList<`a> {
`a head;
struct LinkedList<`a>* next;
} LinkedList<`a>;
// ...
LinkedList<int>* ll = new LinkedList{1, new LinkedList{2, null}};
An "abstract" type can be used, that encapsulates the implementation type but ensures the definition does not leak to the client.
abstract struct Queue<`a> {
LinkedList<`a> front;
LinkedList<`a> rear;
};
extern struct Queue<`a>;
Namespaces
Namespaces exist in Cyclone, similar to C++. Namespaces are used to avoid name clashes in code, and follow the :: notation as in C++. Namespaces can be nested.
namespace foo {
int x;
int f() {
return x;
}
}
namespace bar {
using foo {
int g() {
return f();
}
}
int h() {
return foo::f();
}
}
Pattern matching
Pattern-matching can be accomplished in Cyclone like so:
int g(int a, int b) {
switch ($(a, b - 1)) {
case $(0, y) && y > 1:
return 1;
case $(3, y) && f(x + y) == 7:
return 2;
case $(4, 72):
return 3;
default:
return 4;
}
}
A let declaration is used to match a pattern and expression.
typedef struct Pair {
int x;
int y;
} Pair;
void f(Pair p) {
let Pair(first, second) = p;
// equivalent to:
// int first = p.x;
// int second = p.y;
// ...
}
Type inference
In Cyclone, rather than using auto like C and C++ or var in Java and C#, Cyclone instead uses _ (an underscore) to denote a type-inferred variable.
_ x = (SomeType*)malloc(sizeof(SomeType));
// instead of:
SomeType x = (SomeType*)malloc(sizeof(SomeType));
_ myNumber = 100; // inferred to int
Exceptions
Cyclone features exceptions. An uncaught exception will halt the program. Like Java, Cyclone features a null pointer exception, called Null_Exception.
typedef FILE File;
File* f = fopen("/etc/passwd", "r");
try {
int code = getc((File* @notnull)f);
} catch {
case &Null_Exception:
printf("Error: can't open /etc/passwd\n");
return 1;
case &Invalid_argument(s):
printf("Error: invalid argument: %s\n", s);
return 1;
}
One can also manually throw exceptions:
throw new Null_Exception("This is a null exception");
See also
References
- ↑ Jim, Trevor; Morrisett, J. Greg; Grossman, Dan; Hicks, Michael W.; Cheney, James; Wang, Yanling (10 June 2002). "Cyclone: A Safe Dialect of C". Proceedings of the General Track of the Annual Conference on USENIX Annual Technical Conference. ATEC '02. USA: USENIX Association: 275–288. ISBN 978-1-880446-00-3.
- ↑ "Cyclone". cyclone.thelanguage.org. Archived from the original on 21 May 2006. Retrieved 11 December 2023.
- ↑ "Cyclone". Cornell University. Archived from the original on 15 October 2022. Retrieved 30 October 2022.
External links
- Cyclone homepage
- Old web site
- Cyclone - source code repositories
- Cyclone - FAQ
- Cyclone for C programmers
- Cyclone user manual
- Cyclone: a Type-safe Dialect of C by Dan Grossman, Michael Hicks, Trevor Jim, and Greg Morrisett - published January 2005
Presentations: