<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>AdaCore - The GNAT Pro Company &#187; Devt log - Gem of the Week</title>
	<atom:link href="http://www.adacore.com/category/developers-center/gems/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.adacore.com</link>
	<description>AdaCore technology and news</description>
	<pubDate>Sat, 04 Jul 2009 01:31:59 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Gem #68: Let&#8217;s SPARK! - Part 1</title>
		<link>http://www.adacore.com/2009/06/29/gem-68/</link>
		<comments>http://www.adacore.com/2009/06/29/gem-68/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 10:00:45 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2991</guid>
		<description><![CDATA[Ada Gem #68 &#8212; Please note that this is the final Gem before we break for summer. The series will resume on September 7, 2009.
<p>
In this Gem and the next one, we present a simple walk-through of
SPARK's capabilities and its integration with GPS. In this first Gem, we
show how to set up a SPARK project and prove that your SPARK programs
are free from uninitialized variable accesses and that they execute
without run-time errors.</p>]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>With Praxis and AdaCore now teaming up to offer an integration of SPARK
technology inside GPS (see http://www.adacore.com/home/products/sparkpro/),
many GPS users will be interested in trying out the proof capabilities of
SPARK on their own Ada programs. Of course it&#8217;s a little more involved than
that. SPARK is not only a set of tools for verifying high-assurance systems,
but also incorporates a language that must be learned.</p>

<p>The SPARK language is made up of two parts, one of which is a subset
of Ada (whose features will obviously already be familiar to Ada programmers!),
meant to facilitate code understanding and proofs, and the other part being
a specification language, meant to express properties of programs. Quite
conveniently, the SPARK specifications (a.k.a. SPARK annnotations, to
distinguish them from Ada specifications) are expressed within stylized
Ada comments of the following form:</p>


<pre>
         <EM>&#45;&#45;# &lt;some annotation here&gt;</EM>
</pre>


<p>so SPARK annotations don&#8217;t interfere with normal Ada compilation.</p>



<p>This Gem and the next one demonstrate various of the properties
you can prove with SPARK, and how these relate to the SPARK annotations
written by the user. As a simple example, we will take a procedure which
searches linearly for a value in an array, and returns the index, if any,
at which the value is found.</p>


<p>Here is the specification file search.ads:</p>

<pre>
<b>package</b> Search <b>is</b>

  <b>type</b> IntArray <b>is</b> <b>array</b> (Integer <b>range</b> &lt;&gt;) <b>of</b> Integer;

  <b>procedure</b> Linear_Search
    (Table : <b>in</b> IntArray;
     Value : <b>in</b> Integer;
     Found : <b>out</b> Boolean;
     Index : <b>out</b> Integer);

<b>end</b> Search;
</pre>


<p>And the body file search.adb:</p>

<pre>
<b>package</b> <b>body</b> Search <b>is</b>

  <b>procedure</b> Linear_Search
    (Table : <b>in</b> IntArray;
     Value : <b>in</b> Integer;
     Found : <b>out</b> Boolean;
     Index : <b>out</b> Integer) 
  <b>is</b>
     I : Integer := 0;
  <b>begin</b>
     Found := False;

     <b>while</b> I &lt;= Table&#8217;Last <b>loop</b>
        <b>if</b> Table(I) = Value <b>then</b>
           Found := True;
           Index := I;
           <b>exit</b>;
        <b>end</b> <b>if</b>;
        I := I + 1;
     <b>end</b> <b>loop</b>;
  <b>end</b> Linear_Search;

<b>end</b> Search;
</pre>


<p>Let&#8217;s first get set up for using SPARK:</p>


<p>
1. Copy the files search.ads and search.adb into a directory named search.<br/>
2. Open GPS with a default project in the same directory.<br/>
3. Expand file search.adb.<br/>
4. Select SPARK/SPARKMake from the menu. This generates a file search.idx.<br/>
5. Copy the following code to a file called search.cfg:</p>

<pre>
  <b>package</b> Standard <b>is</b>
     <b>type</b> Integer <b>is</b> <b>range</b> -2**31 .. 2**31-1;
  <b>end</b> Standard;
</pre>

<p>
6. From the Menu, select Project/Edit Project Properties.<br/>
7. Go to the page Switches/Examiner.<br/>
8. Select the following options:
</p>

<pre>
  Index File            : search.idx
  Configuration File    : search.cfg
  Analysis              : Data Flow only
  Generate VCs          : yes (check it)
</pre>


<p>That&#8217;s it!</p>

<p>Now open search.adb and select SPARK/Examine File.
The SPARK Examiner runs and outputs the following messages:</p>

<pre>
       Flow Error 602 - The undefined initial value <b>of</b> Index may be
                         used <b>in</b> the derivation <b>of</b> Index
       Warning 402 - Default assertion planted to cut the <b>loop</b>
       Note - Information flow analysis <b>not</b> carried <b>out</b>
</pre>


<p>The Flow Error indicates that, although Index is an out parameter, it
is not initialized on all paths through Linear_Search. One could argue
that our intent here is to access Index only when Found is set to
True. SPARK considers initialization errors too serious to allow such
subtleties, and requires that all paths through the procedure must initialize
all out parameters. Let&#8217;s comply and initialize Index:</p>

<pre>
  <b>begin</b>
     Found := False;
     Index := 0;
</pre>


<p>After we rerun the Examiner, we are left with a Note that is simply a
reminder of our choice of options, and a Warning that we will
explain in the next Gem.</p>



<p>Now, we can continue with proving that our procedure is free from run-time
errors, such as integer overflow and out-of-bounds array accesses. Select
SPARK/Simplify All. The SPARK Simplifier runs. To see the result of this
tool&#8217;s execution, select SPARK/POGS. This opens a file search.sum, which summarizes
all the proofs in the following table:</p>

<pre>
VCs <b>for</b> procedure_linear_search :
<EM>&#45;&#45;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</EM>
     |       |                     |  <EM>&#45;&#45;&#8212;Proved In&#8212;&#8211;  |       |       |</EM>
#    | From  | To                  | vcg | siv | plg | prv | False | TO <b>DO</b> |
<EM>&#45;&#45;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</EM>
1    | start | rtc check @ 13      |     | YES |     |     |       |       | 
2    | start |    assert @ 15      |     | YES |     |     |       |       | 
3    | 15    |    assert @ 15      |     | YES |     |     |       |       | 
4    | 15    | rtc check @ 16      |     |     |     |     |       |  YES  | 
5    | 15    | rtc check @ 18      |     | YES |     |     |       |       | 
6    | 15    | rtc check @ 21      |     |     |     |     |       |  YES  | 
7    | 15    |    assert @ finish  | YES |     |     |     |       |       | 
8    | 15    |    assert @ finish  | YES |     |     |     |       |       | 
<EM>&#45;&#45;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</EM>
</pre>


<p>Each line corresponds to a Verification Condition (VC), which must be
proved in order to guarantee that the program is free from run-time
errors. Each column corresponds to the result of the proof attempt.
If YES appears in one of the 4 &#8220;Proved In&#8221; columns, the proof was
successful. If YES appears in the &#8220;False&#8221; column, there is something
definitely wrong. If &#8220;YES&#8221; appears in the &#8220;TO DO&#8221; column, we don&#8217;t
know: either the program is wrong, or it is too complex to prove.</p>



<p>Since column &#8220;TO DO&#8221; is not empty here, not all proofs were successful.
In the next Gem, we will give you more details about failed
proofs. The reason for the failures here is that program
Linear_Search is incorrect, meaning that run-time errors can be
raised. To see this, just complete the program with the following code
in main.adb, and build the executable.</p>

<pre>
<b>with</b> Search;
<b>use</b> Search;

<b>procedure</b> Main <b>is</b>
   Table : IntArray(1..10) := (<b>others</b> =&gt; 0);
   Found : Boolean;
   Index : Integer;
<b>begin</b>
   Linear_Search(Table, 0, Found, Index);
<b>end</b> Main;
</pre>


<p>Now run the executable, and it raises an exception:</p>

<pre>
   raised CONSTRAINT_ERROR : search.adb:16 index check failed
</pre>


<p>This is because we are passing an array to Linear_Search that starts
at index 1 in its parameter Table, whereas Linear_Search loop assumes
that the array starts at index 0. SPARK correctly assumes that we can
pass in such an array to Linear_Search, and thus it fails to prove that
Linear_Search is free from run-time errors.</p>



<p>Let&#8217;s correct the code of Linear_Search:</p>

<pre>
  <b>procedure</b> Linear_Search
    (Table : <b>in</b> IntArray;
     Value : <b>in</b> Integer;
     Found : <b>out</b> Boolean;
     Index : <b>out</b> Integer) <b>is</b>
  <b>begin</b>
     Found := False;
     Index := 0;

     <b>for</b> I <b>in</b> Integer <b>range</b> Table&#8217;<b>Range</b> <b>loop</b>
        <b>if</b> Table(I) = Value <b>then</b>
           Found := True;
           Index := I;
            <b>exit</b>;
        <b>end</b> <b>if</b>;
     <b>end</b> <b>loop</b>;
  <b>end</b> Linear_Search;
</pre>


<p>Let&#8217;s do it again: Examine, Simplify All, POGS &#8230;<br/>
This time, columns &#8220;False&#8221; and &#8220;TO DO&#8221; are empty, meaning that all proofs were
successful.</p>

<pre>
VCs <b>for</b> procedure_linear_search :
<EM>&#45;&#45;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</EM>
     |       |                     |  <EM>&#45;&#45;&#8212;Proved In&#8212;&#8211;  |       |       |</EM>
#    | From  | To                  | vcg | siv | plg | prv | False | TO <b>DO</b> |
<EM>&#45;&#45;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</EM>
1    | start | rtc check @ 11      |     | YES |     |     |       |       | 
2    | start | rtc check @ 13      |     | YES |     |     |       |       | 
3    | start |    assert @ 13      |     | YES |     |     |       |       | 
4    | 13    |    assert @ 13      |     | YES |     |     |       |       | 
5    | 13    |    assert @ 13      |     | YES |     |     |       |       | 
6    | 13    | rtc check @ 14      |     | YES |     |     |       |       | 
7    | 13    | rtc check @ 16      |     | YES |     |     |       |       | 
8    | 13    |    assert @ finish  | YES |     |     |     |       |       | 
9    | 13    |    assert @ finish  | YES |     |     |     |       |       | 
<EM>&#45;&#45;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</EM>
</pre>


<p>Thus, we have proved that procedure Linear_Search is free from run-time
errors.</p>



<p>In the next Gem, after the summer break, we will prove that procedure Linear_Search actually
respects a given contract.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/06/29/gem-68/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #67: Managing the GPS Workspace</title>
		<link>http://www.adacore.com/2009/06/15/gem-67/</link>
		<comments>http://www.adacore.com/2009/06/15/gem-67/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 10:00:21 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2981</guid>
		<description><![CDATA[Ada Gem #67 &#8212; GPS has a multitude of views  and editors, several of which may be displayed
on the screen at the same time. It is based on a very flexible desktop that
helps you organize these windows the way you prefer.  This Gem describes some
of the lesser-known aspects of the GPS desktop.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>When you open GPS initially, it shows a number of views: the Messages
window (which can never be closed), the Project View, showing the list of
files in your project, the Outline View, which shows the list of subprograms in
the current edit, the Scenario View listing the scenario variables in your
project, and a Welcome window to help you get started.</p>



<p>When several windows share the same screen area (which is the case for the
project view and the outline view in the default desktop), they are organized
into notebooks, and it&#8217;s possible to show any view by clicking on its
associated tab. By default, GPS will now show the tabs if there is only one
window in a given area, to save screen real estate. This behavior can be
changed through the &#8220;Notebook Tabs Policy&#8221; preference. You can also change the
location of the tabs (which by default appear below the window) through the
&#8220;Notebook Tabs Position&#8221; preference. This latter preference configures the
default location, though, and you can change it on a per-notebook basis by
right-clicking in any of the tabs and changing the tabs position.
</p>


<p>Windows can also be made to float. They are then put under the control of the
operating system (or the window manager), and you can move them to another
screen, another virtual desktop, iconify them, and so on. The window will have its own
entry in your systems panel (the bar that is generally displayed at the bottom
of the screen and shows all open windows). GPS has a mode where all windows it
creates are made floating by default (this is the &#8220;All Floating&#8221;
preference). When this mode is not activated, you can move a floating window
back into GPS using one of two methods: the /Window/Floating menu, or by
clicking on the [x] in the window&#8217;s title bar when the &#8220;Destroy Floating&#8221;
preference is unset; at that point, instead of closing the window, GPS will
simply put it back in its own window. If you really want to close it, you
have to click a second time on [x].</p>



<p>Only one of the views has the focus at any given time, and it receives all
keyboard input. Its title bar is then highlighted in a different color (which
you configure in the preferences). To save some space on the screen, you
could choose to hide the title bars. Indeed, it is obvious most of the time
what each window is after you have used them a few times. The only case where
you might be missing info is for editors (since the title bar includes the
full name of the file). However, this name also appears in GPS&#8217;s own title
bar. When the title bar is hidden, the notebook&#8217;s tab will be color
highlighted to show the currently active window.
</p>


<p>When a window is not currently visible on the screen (most often this will be
when the Messages window is below the Locations window for instance), its tab
is highlighted in a special color to bring attention to it and encourage you
to check what has changed in that window.</p>



<p>It is rather obvious (or so we hope) that the views can be resized as you see
fit simply by dragging the separators between those windows (that is, click on
the separator, hold the mouse button, and move the mouse up/down or left/right,
depending on the orientation of the separator). The resizing can take one of
two forms: either a simple line overlaid on top of the windows to show where
the separator will end up when you release the mouse, or by redrawing the
windows each time you move the mouse. This behavior can also be configured in
the preferences.</p>



<p>However, did you know that you can actually create any number of new areas on the
desktop (which we call the MDI, for Multiple Document Interface)? This can be
done in a number of ways. The easiest to discover is to use the menu
/Window/Split Side-by-Side or /Window/Split Up-Down. For instance, assuming
you have the default desktop loaded in GPS, select the project view. Then
select the menu /Window/Split Up-Down. This will put the outline view in its
own area below the project view, allowing you to see both at the same time.</p>



<p>However, the most flexible way to reorganize windows is by using drag and
drop. Start by clicking on the title bar or the tab of any window. Then,
without releasing the mouse button, move your mouse to where you would like to
put the window you clicked on. Note how a pop-up window appears on top of the
GPS window to describe what will happen when you release the mouse. There are
six places where you can drop a window: if you release the mouse in the middle
of an existing window, the two windows will be stacked into a notebook; if you
release on any of the sides of an existing window (there is a margin a few pixels wide
on each side), the existing window will be split and the window you are
moving will be displayed next to it; finally, you can also release the mouse
outside of the GPS window altogether to make the window floating.</p>



<p>As an additional bonus, if you press the shift key when you are dropping an
editor window, a new view will be created (showing the same contents) instead
of moving the initial editor. This allows you to view several locations in a
given file, which is often useful when you want to view data structures when
writing code, or when comparing several sections of code.</p>



<p>My own preferred organization (on a wide screen) is as follows: I have two
editors side by side (for instance spec and body). Then on the left side I
display the Windows view (/Tools/Views/Windows menu), which provides a fast way
to select and bring to the front any window no matter where it currently is
on the screen. This is a also a convenient place from which to start the drag-and-drop
operations (clicking on a file and dropping it where I want to put the editor). Below
this Windows view I have the Bookmarks view, which allows me to
save places within any of the editors (through the /Edit/Create Bookmark menu),
and come back to them later.  Below the two editors, I display the Messages
window and the Locations window side by side, so that I can see compilation
errors easily, while keeping an eye on whether GPS has reported an error in
its messages window. Finally, on the right-hand side of the screen I display
the Outline view, since this is such a great way to move fast within a file,
and the Tasks view that shows what&#8217;s being executed in the background (and
provides  a way  to monitor  the progress  of compilations when using the -d
switch to gnatmake). As you see, there are quite a number of views. To save
space, I usually hide title bars (which as explained above are not necessary
once you know what the windows are for), as well as the status bar at the
bottom of the GPS window (since the task view displays the same information
already).
</p>


<p>Once you have found a layout that you like, however, you probably want to
reuse it every time you open GPS. This is called saving the desktop. This
process is very configurable, to adapt to the various needs that people might
have:</p>


<p>
 - The default is for GPS to save the project-specific desktop. This means that
   the layout you have just created will be saved automatically on exit, and
   reapplied when loading the same project later on. If you load another
   project, the default layout will be used. One reason to do that is to save
   the currently opened files in the desktop (this is controlled by another
   preference, &#8220;Save Editor is Desktop&#8221;, where you decide whether you want to
   save editors or not, and if you do, whether only project-specific editors
   will be saved or any file that happens to be opened at that time.</p>


 
<p>- If you want to reuse the same layout for all projects on which you work,
   you should make sure the preference &#8220;General/Save Project-Specific Desktop
   on Exit&#8221; is disabled. This means that a single version of the desktop will
   be saved, and will apply to all projects (in this case it might be a good
   idea to remove the file  $HOME/desktop.xml prior to launching GPS the first
   time, so that any trace of project-specific desktop is wiped out). In such
   a case, one of the drawbacks is that you might not want to save the editors
   since they would not necessarily match the next project you load.</p>



<p>The method I have been using is the following: after removing the desktop.xml
file as described above, I launch GPS and set up the various views as I like,
but do not open any editor. I then save the current desktop as the default
through the menu /File/Save Move/Default Desktop. I then ensure that the
preference to save project-specific desktops is on, as well as the preference
to save the editors in the desktop. This ensures that every time I open a
project that I&#8217;ve never opened before, I get the default desktop (with no editor), but
when I open a project that I have already opened before, then I get the same editors
(and in the same location) as the last time I exited GPS.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/06/15/gem-67/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #66: GPS&#8217;s Key Shortcuts Editor</title>
		<link>http://www.adacore.com/2009/06/01/gem-66/</link>
		<comments>http://www.adacore.com/2009/06/01/gem-66/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 10:00:20 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2812</guid>
		<description><![CDATA[Ada Gem #66 &#8212; Most GPS features are accessible through menus and contextual menus. However,
for maximum efficiency most users prefer to use keyboard shortcuts. Although
GPS comes with a number of predefined shortcuts, you might want to adapt them
to your own habits, especially if you are moving from a previous editor.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>There are several ways in which the keyshortcuts can be changed in GPS.</p>



<p>One of the common cases is a user previously using the Emacs editor. GPS
comes with a plug-in that will change the default key bindings in GPS. You
just need to go to the /Tools/Plug-ins menu, and activate the &#8220;emacs.xml&#8221;
plug-in. Note that for full compatibility with Emacs, you should also
load some additional plug-ins (these are documented in the Description tab).</p>



<p>Similar plug-ins can be built for other editors, and shared with the rest
of your team.</p>



<p>The most flexible method, however, is to go to the /Edit/Key Shortcuts menu.
This will open a dialog in which you can configure shortcuts for any of
the menus or any of the actions that GPS has created.</p>



<p>At this point, we should explain the difference between actions and
menus. Internally, GPS exports its various features to the GUI as named
actions. These actions are implemented either in Ada or using one of the
scripting languages supported by GPS (python or XML for instance). They
are organized into categories to make them easier to find. You can also
create your own actions through XML files (see the GPS documentation for
more details).</p>



<p>Most of the time, these actions are hidden and called in the background.
But you can activate the &#8220;execute extended&#8221; plug-in if you want to be
able to directly execute these commands by name, as Emacs does through its
&#8220;M-x&#8221; key binding.</p>



<p>Some of these actions are then bound to menus or contextual menus.</p>



<p>Back to the Key Shortcuts editor. The main part of the dialog shows the
list of actions exported by GPS. These are organized into categories. One
of them is special, and is called &#8220;Menus&#8221;. It gives you access to all the
menus of GPS (so some actions are accessible in two places, either by
category/name, or by the menu). If you activate the &#8220;Flat List&#8221; button,
the actions will instead be listed alphabetically and the categories will no
longer be visible.
</p>


<p>Next to each action or menu, GPS displays the shortcut associated with that
action. One limitation here is that the shortcut is either shown next to the
menu or next to the action (depending on how it was setup), but not both.</p>



<p>Here&#8217;s a small trick if you want to find out what a shortcut is bound to.
You can click on both the &#8220;Flat List&#8221; and the &#8220;Shortcuts Only&#8221; buttons.
This will list only those actions which currently have a shortcut
associated. By clicking on the &#8220;Shortcut&#8221; column header, you can then sort the
list by shortcut, thus making it easy to find out what a specific key shortcut
does. </p>



<p>Through this dialog, you can change the shortcut for any of the actions.
Simply select that action in the list, then press the &#8220;Grab&#8221; button, and you
can then press the keyboard shortcut that you want to assign to it.
</p>


<p>Key shortcuts are not limited to a single key (which on a standard keyboard
would not provide enough shortcuts for those Emacs users). You can in fact
have a series of shortcuts, as in &#8220;Control-x k&#8221;, which is used in Emacs
to close the current window. Due to limitations in the gtk+ toolkit on which
GPS is based, however, the menus are only able to display single shortcuts, so
if you assign the above shortcut to a menu you can use the shortcut but it
will not be visible in the menu itself.</p>



<p>Once you close the dialog with &#8220;OK&#8221;, the shortcut becomes effective
immediately, and will be preserved from session to session. In fact, the
key shortcuts you just created are saved in an XML file (keys.xml) in your
$HOME/.gps directory. You can thus copy this file to other accounts or setups
to automatically get the same shortcuts again.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/06/01/gem-66/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #65: gprbuild</title>
		<link>http://www.adacore.com/2009/05/18/gem-65/</link>
		<comments>http://www.adacore.com/2009/05/18/gem-65/#comments</comments>
		<pubDate>Mon, 18 May 2009 10:00:36 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2790</guid>
		<description><![CDATA[Ada Gem #65 &#8212; gprbuild is a new program builder, superseding gnatmake. It supports multiple languages, automatically manages source dependencies, and reduces the need for recompilation. This Gem describes a high-level view of how gprbuild works.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>GNAT allows for a great deal of flexibility in compiling applications. The
traditional method is to use gnatmake on the command line, specifying the
list of source directories by using &#8220;-I&#8221; switches, and letting gnatmake decide
which files need to be recompiled. One drawback of this approach is that it
only works for Ada files. If your application uses sources written in other
languages (which is probably the case for the majority of serious applications),
then you need some kind of wrapper around gnatmake. This is typically done
via a Makefile: first you recompile C, C++, and other source files using standard
Makefile techniques, then invoke gnatmake to handle the Ada sources, and
finally (although this can also be done as part of gnatmake) bind and link
your application.</p>



<p>Gnatmake is what we call a builder. Its role is to examine all source
files in your application and decide which ones need to be recompiled. It then
relies on other tools to do the actual compilation (gcc), bind (gnatbind) and
link (gnatlink).</p>


<p>
A few releases ago, a new tool called gprbuild was introduced in the GNAT technology.
It is also a builder, reusing and extending gnatmake to support multilanguage applications.
This means it knows how to handle C, C++, and many other languages, and is able to
determine which source files for each language need to be recompiled. One benefit is
that you no longer need to depend on a Makefile to compile those source files prior to
binding and linking.</p>



<p>Gprbuild has been carefully designed so that no hard coding was done for any
of the languages. Instead, all the information resides in a configuration file
(typically having the extension &#8220;.cgpr&#8221;): how to compile a file, how to decide whether it
is up to date, what files get generated as a result of the compilation, and so on.</p>



<p>These configuration files have a syntax similar to that of the project files
themselves. They can be hand-edited as required, and maintained in your
version control system as for any other component of the environment. </p>



<p>However, developing a configuration file is not always easy, especially when you
are using different compiler chains (such as GNAT for Ada files and Diab for C). In
particular, the link phase becomes harder to describe. Add to that support for
multiple platforms, cross-compilation, libraries, and other subtleties, and the
complexity increases quickly.</p>



<p>AdaCore has already taken care of a lot of possible compilers and combinations,
so that you do not have to redo that complex setup yourself. We have created a
knowledge base that describes the configuration for various common scenarios.</p>



<p>GNAT comes with an additional command-line tool, called gprconfig, which is
generally spawned transparently by gprbuild, so you don&#8217;t have to invoke it directly in
most cases. The role of gprconfig is to create the configuration file based on
your specific set of compilers, getting information from the knowledge base.</p>



<p>Now that we&#8217;ve described the general organization of things, let&#8217;s show a
concrete example.</p>



<p>Let&#8217;s assume your application is made up of two files, bar.adb and foo.c, with the
following code (not very interesting, admittedly, since it will do exactly nothing):</p>


<pre>
<b>procedure</b> Bar <b>is</b>
   <b>procedure</b> Foo;
   <b>pragma</b> Import (C, Foo);
<b>begin</b>
   Foo;
<b>end</b> Bar;
</pre>

<pre>
int foo () {}
</pre>



<p>gprbuild only works with project files (there are no command-line options to
specify source directories, for instance). So you need to write one. The
basic elements of information you need to specify in a project file are: languages (C and
Ada in our case), source directories and source files (implicit in our case),
and main source files (bar.adb in our case). So the project file default.gpr
looks like:</p>


<pre>
<b>project</b> Default is
   <b>for</b> Languages <b>use</b> (&quot;C&quot;, &quot;Ada&quot;);
   <b>for</b> Main <b>use</b> (&quot;bar.adb&quot;);
<b>end</b> Default;
</pre>



<p>At this point everything is set up, and we can just spawn gprbuild with the command:</p>

<pre>
gprbuild -Pdefault
</pre>



<p>Since we did not specify a configuration file through a &#8211;config switch,
gprbuild will automatically generate one by spawning gprconfig and telling it
we want to find the first available Ada and C compilers on the PATH. Gprconfig
will then create a configuration file called auto.cgpr, which
gprbuild in turn uses to build our executable.
</p>


<p>If you relaunch the same command again immediately, no recompilation takes
place, not even for the C file.</p>



<p>Notice also how gprconfig selects the first matching compiler on the PATH for
each language. If you want to force the use of specific compilers (that might
not even be on your PATH), you will need to spawn gprconfig manually yourself
and pass it a &#8211;config switch. This creates a configuration file which you can
then pass along on your invocation of gprbuild.</p>]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/05/18/gem-65/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #64: Handling Multiple-Unit Source Files</title>
		<link>http://www.adacore.com/2009/05/04/gem-64/</link>
		<comments>http://www.adacore.com/2009/05/04/gem-64/#comments</comments>
		<pubDate>Mon, 04 May 2009 10:00:40 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2789</guid>
		<description><![CDATA[Ada Gem #64 &#8212; This Gem describes how to compile applications in GNAT when source files
contain multiple units. The preferred approach is to split source files, and
here we describes how this can be done, although GNAT also provides a
workaround that allows you to keep your existing files.
]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>In lots of legacy systems that were initially developed with
technologies other than GNAT, a single source file might include several
Ada units (or both spec and body of a single unit).</p>


<p>Where possible, it is best to follow GNAT&#8217;s traditional approach and split
these files into several files. The main advantage this provides is to
limit the amount of recompilation that gnatmake and gprbuild will do. When
several units are found in the same file, modifying any of them will force
recompilation of all files that depend on any of the units found in the
file. In particular, changing the body of a unit when the spec is in the
same source file will force recompilation of all units that depend on
it. This is contrary to the whole concept of separate specifications.</p>


<p>This is also the recommended method in the Ada Quality and Style manual, so
this should really be the preferred approach where possible.</p>



<p>Such splitting of source files can be done through the gnatchop command line
tool. If you want to keep the original (multiple-unit) source files and
keep modifying these, we recommend using the &#8220;-r&#8221; switch, which will force
GNAT&#8217;s error messages to reference the original (unsplit) file.</p>



<p>If however you do not intend to keep them, you should not use &#8220;-r&#8221;.</p>



<p>Most likely the &#8220;-w&#8221; switch will also come in handy, to force overwriting of
previously split files. Also, since you are recreating the source files that
gnatmake sees, you should use the &#8220;-m&#8221; switch for gnatmake so that it doesn&#8217;t
pay attention to timestamps. Otherwise you would end up recompiling all files all the
time.</p>



<p>Calling gnatchop cannot be done automatically by gnatmake. Instead, you should
have a script or a Makefile that first calls gnatchop, and then spawns
gnatmake to do the actual compilation.</p>



<p>However, in some cases it isn&#8217;t possible to split the source files. Most
often, this is because the files are under configuration control and you want
to preserve history. In other cases, this is because you still want to compile
with your older compiler.</p>



<p>GNAT provides a workaround in cases where you cannot split your source files
and cannot or do not want to change your build methods to use gnatchop. Let us
emphasize that this is really considered as only a workaround, and is not fully
supported by all the tools. For instance, the &#8220;-gnatD&#8221; and &#8220;-gnatR&#8221; switches
are currently not compatible with the pragmas described below. More
important perhaps, GPS will have some known limitations when using
multiple-unit source files (cross-references will not work in a lot of cases, and
compiling the current file will fail if it contains multiple units)</p>



<p>You have to let GNAT know about your source-file organization, which can be
done in several ways.</p>



<p>Method 1: If you are using project files, you can add or create a package Naming
 inside your project file, and use a syntax like:</p>


 <pre>
 <b>package</b> Naming <b>is</b>
   <b>for</b> Specification (&quot;unit1&quot;) <b>use</b> &quot;file1.ada&quot; <b>at</b> 1;
   <b>for</b> Implementation (&quot;unit1&quot;) <b>use</b> &quot;file1.ada&quot; <b>at</b> 2;
 <b>end</b> Naming;
</pre>



<p> The index after the <b>at</b> starts at 1 and indicates the position of the
 unit inside the source file.</p>



<p> You can either create this Naming package manually by editing the project
 file, or else by using the gnatname command-line tool. This tool will traverse all the
 directories you pass it via its &#8220;-d&#8221; switch, check each file in them, and
 determine what unit or units they contain. It will then create a new project
 file called my_project_naming.gpr, and modify the project you specified on
 the command line in a manner similar to:</p>


 <pre>
 <b>with</b> &quot;my_project_naming&quot;;
 <b>project</b> My_Project <b>is</b>
    <b>package</b> Naming <b>renames</b> My_Project_Naming.Naming;
 <b>end</b> My_Project;
</pre>



<p> GPS was recently modified to properly support such project files, and
 properly preserve the existing &#8220;<b>at</b>&#8221; information when you edit a project,
 as well as to allow you to create new naming exceptions directly from the
 graphical interface.</p>



<p>Method 2: If you are not using project files yet, you can specify the same information
 by using pragmas in a configuration file. Through its &#8220;-c&#8221; switch, gnatname is
 also able to generate this file of pragmas. The general form of the configuration file is:</p>


 <pre>
 <b>pragma</b> Source_File_Name
   (Unit1, Spec_File_Name =&gt; &quot;file1.ada&quot;, Index =&gt; 1);
 <b>pragma</b> Source_File_Name
   (Unit1, Body_File_Name =&gt; &quot;file1.ada&quot;, Index =&gt; 2);
</pre>



<p> where the information is similar to what was specified in the project
 file example above.</p>



<p>There is a difference between using these project attributes or pragmas, and
using &#8220;gnatchop -r&#8221; as we described in the first part: while there is a single
command to spawn, and no duplication of source files with the pragmas, you
still have the issue that gnatmake will recompile everything that depends on
any unit in the file. When using gnatchop, however, that problem does not
exist, because gnatmake sees single-unit source files. Also, the pragma-based
method is not fully supported by all the tools yet, so the preferred approach
is really to split your files (and preferably replace the multiple-unit source
files with the resulting single-unit files).</p>]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/05/04/gem-64/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #63: The Effect of Pragma Suppress</title>
		<link>http://www.adacore.com/2009/04/21/gem-63/</link>
		<comments>http://www.adacore.com/2009/04/21/gem-63/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 10:00:50 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2788</guid>
		<description><![CDATA[Ada Gem #63 &#8212; The features of Ada have generally been designed to prevent violating
the properties of data types, enforced either by compile-time rules or,
in the case of dynamic properties, by using run-time checks.  Ada allows
run-time checks to be suppressed, but not with the intent of allowing
programmers to subvert the type system.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>One of Ada&#8217;s key strengths has always been its strong typing.
The language imposes stringent checking of type and subtype properties
to help prevent accidental violations of the type system that are a common
source of program bugs in other less-strict languages such as C.  This is
done using a combination of compile-time restrictions (legality rules), that
prohibit mixing values of different types, together with run-time checks
to catch violations of various dynamic properties.  Examples are checking
values against subtype constraints and preventing dereferences of null
access values.</p>



<p>At the same time, Ada does provide certain &#8220;loophole&#8221; features, such as
Unchecked_Conversion, that allow selective bypassing of the normal safety
features, which is sometimes necessary when interfacing with hardware or
code written in other languages.</p>


<p>Ada also permits explicit suppression of the run-time checks that are
there to ensure that various properties of objects are not violated.
This suppression can be done using pragma Suppress, as well as by using
a compile-time switch on most implementations (in the case of GNAT, with
the -gnatp switch).</p>

<p>In addition to allowing all checks to be suppressed, Pragma Suppress 
supports suppression of specific forms of check, such as Index_Check
for array indexing, Range_Check for scalar bounds checking, and
Access_Check for dereferencing of access values.  (See section 11.5
of the Ada Reference Manual for further details.)</p>

<p>Here&#8217;s a simple example of suppressing index checks within a specific
subprogram:</p>

<pre>
  <b>procedure</b> Main <b>is</b>
     <b>procedure</b> Sort_Array (A : <b>in</b> <b>out</b> Some_Array) <b>is</b>
        <b>pragma</b> Suppress (Index_Check);  &#8212; eliminate check overhead
     <b>begin</b>
        &#8230;
     <b>end</b> Sort_Array; 
  <b>end</b> Main;
</pre>

<p>Unlike a feature such as Unchecked_Conversion, however, the purpose of
check suppression is not to enable programs to subvert the type system,
though many programmers seem to have that misconception.</p>



<p>What&#8217;s important to understand about pragma Suppress is that it only gives
permission to the implementation to remove checks, but doesn&#8217;t require such
elimination.  The intention of Suppress is not to allow bypassing of Ada
semantics, but rather to improve efficiency, and the Ada Reference Manual
has a clear statement to that effect in the note in RM-11.5, paragraph 29:</p>


 
<p> <em>There is no guarantee that a suppressed check is actually
  removed; hence a pragma Suppress should be used only for
  efficiency reasons.</em></p>



<p>There is associated Implementation Advice that recommends that implementations
should minimize the code executed for checks that have been suppressed, but
it&#8217;s still the responsibility of the programmer to ensure that the correct
functioning of the program doesn&#8217;t depend on checks not being performed.</p>



<p>There are various reasons why a compiler might choose not to remove
a check.  On some hardware, certain checks may be essentially free, such as
null pointer checks or arithmetic overflow, and it might be impractical or
add extra cost to suppress the check.  Another example where it wouldn&#8217;t
make sense to remove checks is for an operation implemented by a call to
a run-time routine, where the check might be only a small part of a more
expensive operation done out of line.</p>



<p>Furthermore, in many cases GNAT can determine at compile time that a given
run-time check is guaranteed to be violated.  In such situations, it gives
a warning that an exception will be raised, and generates code specifically
to raise the exception.  Here&#8217;s an example:</p>

<pre>
   X : Integer <b>range</b> 1..10 := &#8230;;

   ..

   <b>if</b> A &gt; B <b>then</b>
      X := X + 1;
      ..
   <b>end</b> <b>if</b>;
</pre>


<p>For the assignment incrementing X, the compiler will normally generate
machine code equivalent to:</p>

<pre>
   Temp := X + 1;
   <b>if</b> Temp &gt; 10 <b>then</b>
      <b>raise</b> Constraint_Error;
   <b>end</b> <b>if</b>;
   X := Temp;
</pre>


<p>If range checks are suppressed, then the compiler can just generate the
increment and assignment.  However, if the compiler is able to somehow
prove that X = 10 at this point, it will issue a warning, and replace the
entire assignment with simply:</p>

<pre>
   <b>raise</b> Constraint_Error;
</pre>


<p>even though checks are suppressed.  This is appropriate, because (1) we don&#8217;t
care about the efficiency of buggy code, and (2) there is no &#8220;extra&#8221; cost
to the check, because if we reach that point, the code will unconditionally
fail.</p>



<p>One other important thing to note about checks and pragma Suppress is
this statement in the Ada RM (RM-11.5, paragraph 26):</p>


 
<p> <em>If a given check has been suppressed, and the corresponding error
  situation occurs, the execution of the program is erroneous.</em></p>



<p>In Ada, erroneous execution is a bad situation to be in,
because it means that the execution of your program could have arbitrary
nasty effects, such as unintended overwriting of memory.  Note also that
a program whose &#8220;correct&#8221; execution somehow depends on a given check being
suppressed might work as the programmer expects, but could still fail when
compiled with a different compiler, or for a different target, or even with
a newer version of the same compiler.  Other changes such as switching on
optimization or making a change to a totally unrelated part of the code
could also cause the code to start failing.</p>



<p>So it&#8217;s definitely not wise to write code that relies on checks being
removed.  In fact, it really only makes sense to suppress checks once
there&#8217;s good reason to believe that the checks can&#8217;t fail, as a result
of testing or other analysis.  Otherwise, you&#8217;re removing an important
safety feature of Ada that&#8217;s intended to help catch bugs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/04/21/gem-63/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #62: C++ constructors and Ada 2005</title>
		<link>http://www.adacore.com/2009/04/06/gem-62/</link>
		<comments>http://www.adacore.com/2009/04/06/gem-62/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 10:00:25 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2743</guid>
		<description><![CDATA[Ada Gem #62 &#8212; In the previous Gem, we explored how to interface and make simple use
of C++ constructors on the Ada side.
<p>In this Gem, we detail more advanced constructs related to Ada 2005
and C++ constructors.</p>]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>Continuing from the example discussed in the last Gem,
let&#8217;s derive the imported C++ class on the Ada side. For example:</p>

<pre>
 <b>type</b> DT <b>is</b> <b>limited</b> <b>new</b> Root <b>with</b> <b>record</b>
    C_Value : Natural := 2009;
 <b>end</b> <b>record</b>;
</pre>


<p>In this case, the components DT inherited from the C++ side must be
initialized by a C++ constructor, and the additional Ada components
of type DT are initialized by GNAT. The initialization of such an
object is done either by default, or by means of a function returning
an aggregate of type DT, or by means of an extension aggregate:</p>

<pre>
 Obj5 : DT;
 Obj6 : DT := Function_Returning_DT (50);
 Obj7 : DT := (New_Root (30, 40) <b>with</b> C_Value =&gt; 50);
</pre>


<p>The declaration of Obj5 invokes the default constructors: the
C++ default constructor of the parent type takes care of the initialization
of the components inherited from Root, and GNAT takes care of the default
initialization of the additional Ada components of type DT (that is,
C_Value is initialized to value 2009). The order of invocation of
the constructors is consistent with the order of elaboration required by
Ada and C++, meaning that the constructor of the parent type is always called
before the constructor of the derived type.</p>



<p>Let&#8217;s now consider a record that has components whose type is imported
from C++. For example:</p>

<pre>
 <b>type</b> Rec1 <b>is</b> <b>limited</b> <b>record</b>
    Data1 : Root := New_Root (10);
    Value : Natural := 1000;
 <b>end</b> <b>record</b>;

 <b>type</b> Rec2 (D : Integer := 20) <b>is</b> <b>limited</b> <b>record</b>
    Rec   : Rec1;
    Data2 : Root := New_Root (D, 30);
 <b>end</b> <b>record</b>;
</pre>


<p>The initialization of an object of type Rec2 will call the
nondefault C++ constructors specified for the imported components.
For example:</p>

<pre>
 Obj8 : Rec2 (40);
</pre>


<p>Using Ada 2005 we can use limited aggregates to initialize an object
invoking C++ constructors that differ from those specified in the type
declarations. For example:</p>

<pre>
 Obj9 : Rec2 := (Rec =&gt; (Data1 =&gt; New_Root (15, 16),
                         <b>others</b> =&gt; &lt;&gt;),
                 <b>others</b> =&gt; &lt;&gt;);
</pre>


<p>The above declaration uses an Ada 2005 limited aggregate to
initialize Obj9, and the C++ constructor that has two integer
arguments is invoked to initialize the Data1 component instead
of the constructor specified in the declaration of type Rec1. In
Ada 2005, the box in the aggregate indicates that unspecified components
are initialized using the expression (if any) available in the component
declaration. That is, in this case discriminant D is initialized
to value 20, Value is initialized to value 1000, and the
non-default C++ constructor that handles two integers takes care of
initializing component Data2 with values 20 and 30.</p>



<p>In Ada 2005, we can use the extended return statement to build the Ada
equivalent of a C++ nondefault constructor. For example:</p>

<pre>
 <b>function</b> New_Rec2 (V : Integer) <b>return</b> Rec2 <b>is</b>
 <b>begin</b>
    <b>return</b> Obj : Rec2 := (Rec =&gt; (Data1  =&gt; New_Root (V, 20),
                                  <b>others</b> =&gt; &lt;&gt;),
                          <b>others</b> =&gt; &lt;&gt;) <b>do</b>
       <EM>&#45;&#45;  Further actions required for construction of</EM>
       <EM>&#45;&#45;  objects of type Rec2</EM>
       &#8230;
    <b>end</b> <b>record</b>;
 <b>end</b> New_Rec2;
</pre>


<p>In this example, the extended return statement construct is used to
build in place the returned object, whose components are initialized
by means of a limited aggregate. Any further actions associated with
the constructor can be given within the statement part of the extended return.</p>]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/04/06/gem-62/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #61: Interfacing with C++ constructors</title>
		<link>http://www.adacore.com/2009/03/23/gem-61/</link>
		<comments>http://www.adacore.com/2009/03/23/gem-61/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 11:00:34 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2606</guid>
		<description><![CDATA[Ada Gem #61 &#8212; In the previous Gem about generating bindings from C++ headers,
we mentioned, without going into details, how to interface with
C++ constructors in Ada using the CPP_Constructor pragma.

<p>In this Gem we present some common uses of C++ constructors
in mixed-language programs in GNAT, and in the next Gem, we will show
the use of some powerful Ada 2005 features in conjunction with C++ constructors.</p>]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>Let&#8217;s assume that we need to interface with the following
C++ class:</p>


<pre>
<b>class</b> Root {
<b>public</b>:
   <b>int</b>  a_value;
   <b>int</b>  b_value;
   <b>virtual int</b> Get_Value ();
   Root();              // Default constructor
   Root(int v);         // 1st non-default constructor
   Root(int v, int w);  // 2nd non-default constructor
};
</pre>


<p>Using the automatic binding generator, or writing manually, we can
obtain the corresponding package spec:</p>

<pre>
<b>with</b> Interfaces.C; <b>use</b> Interfaces.C;
<b>package</b> Pkg_Root <b>is</b>

   <b>type</b> Root <b>is</b> <b>tagged</b> <b>limited</b> <b>record</b>
       A_Value : int;
       B_Value : int;
   <b>end</b> <b>record</b>;
   <b>pragma</b> Import (CPP, Root);

   <b>function</b> Get_Value (Obj : Root) <b>return</b> int;
   <b>pragma</b> Import (CPP, Get_Value);

   <b>function</b> New_Root <b>return</b> Root&#8217;Class;
   <b>pragma</b> Cpp_Constructor (New_Root, &quot;_ZN4RootC1Ev&quot;);

   <b>function</b> New_Root (v : int) <b>return</b> Root&#8217;Class;
   <b>pragma</b> Cpp_Constructor (New_Root, &quot;_ZN4RootC1Ei&quot;);

   <b>function</b> New_Root (v, w : int) <b>return</b> Root&#8217;Class;
   <b>pragma</b> Cpp_Constructor (New_Root, &quot;_ZN4RootC1Eii&quot;);

<b>end</b> Pkg_Root;
</pre>


<p>On the Ada side, the constructor is represented by a function (whose
name is arbitrary) that returns the class-wide type corresponding to
the imported C++ class. The return type is required to be class-wide rather
than the specific Root type so that the function will not be treated as a
primitive dispatching operation of the type. Although the constructor is
described as a function, it is typically a procedure with an extra implicit
argument (the object being initialized) at the implementation level. GNAT
issues the appropriate call, whatever it is, to initialize the object.</p>



<p>Constructors can appear in the following contexts:</p>



<p>- As the initialization expression of an object of type T<br/>
- As the initialization expression of a record component of type T<br/>
- In a limited aggregate<br/>
- In a limited aggregate used as the expression of a return statement
</p>

<p>Note that all of the above contexts are places where Ada 2005 allows
limited aggregates and calls to functions with limited results to appear,
and in fact it&#8217;s necessary to enable the Ada 2005 compilation mode
(-gnat05) to make use of this feature.</p> 


<p>In a declaration of an object whose type is a class imported from C++,
either the default C++ constructor is implicitly called by GNAT, or
else the required C++ constructor must be explicitly called in the
expression that initializes the object. For example:</p>

<pre>
 Obj1 : Root;
 Obj2 : Root := New_Root;
 Obj3 : Root := New_Root (v =&gt; 10);
 Obj4 : Root := New_Root (30, 40);
</pre>

<p>The first two declarations are equivalent: in both cases, the default C++
constructor is invoked (in the former case the call to the constructor is
implicit, and in the latter case the call is explicit in the object
declaration). Obj3 is initialized by the C++ nondefault constructor
that takes an integer argument, and Obj4 is initialized by the
nondefault C++ constructor that takes two integers.
</p>

<p>It&#8217;s worth pointing out that normally it&#8217;s not permitted to call a class-wide
function to initialize an object of a specific type, and it&#8217;s only in the case of
these special imported constructor functions that the compiler allows this usage.</p>

<p>In the next Gem we will explore how to derive and extend imported C++
classes on the Ada side, and show uses of constructors in Ada 2005 extended
return and limited aggregates.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/03/23/gem-61/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #60: Generating Ada bindings for C++ headers</title>
		<link>http://www.adacore.com/2009/03/09/gem-60-generating-ada-bindings-for-c-headers/</link>
		<comments>http://www.adacore.com/2009/03/09/gem-60-generating-ada-bindings-for-c-headers/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 11:00:03 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2597</guid>
		<description><![CDATA[Ada Gem #60 &#8212; In Gem #59 we saw how simple it is to automatically generate Ada
bindings for C header files. In this Gem, we will see that, similarly,
it's now also possible to generate Ada bindings for C++ header files.]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>Generating bindings for C++ headers is done using the same options as for
C headers, again using the G++ driver. This is because the binding generation
tool takes advantage of the full C and C++ front ends readily available
with GCC, and then translates its internal representation into corresponding
Ada code.
</p>


<p>In this mode, C++ classes will be mapped to Ada tagged types, constructors
will be mapped using the CPP_Constructor pragma, and, when possible,
multiple inheritance of abstract classes will be mapped to Ada interfaces.
</p>

<p><strong>A complete example</strong></p>


<p>For example, given the following C++ header file called animals.h:
</p>
<pre>
<b>class</b> Carnivore {
<b>public</b>:
  <b>virtual int</b> Number_Of_Teeth () = 0;
};

<b>class</b> Domestic {
<b>public</b>:
  <b>virtual void</b> Set_Owner (<b>char</b>* Name) = 0;
};

<b>class</b> Animal {
<b>public</b>:
  int Age_Count;
  <b>virtual void</b> Set_Age (<b>int</b> New_Age);
};

<b>class</b> Dog : Animal, Carnivore, Domestic {
<b>public</b>:
  <b>int</b> Tooth_Count;
  <b>char</b> *Owner;

  <b>virtual int</b>  Number_Of_Teeth ();
  <b>virtual void</b> Set_Owner (<b>char</b>* Name);

  Dog();
};
</pre>


<p>We generate an Ada package with:</p>

<pre>
$ g++ -c -fdump-ada-spec animals.h
</pre>


<p>which generates a file animals_h.ads that has the following contents:</p>

<pre>
<b>package</b> animals_h <b>is</b>

   <b>package</b> Class_Carnivore <b>is</b>
     <b>type</b> Carnivore <b>is</b> <b>limited</b> <b>interface</b>;
     <b>pragma</b> Import (CPP, Carnivore);

     <b>function</b> Number_Of_Teeth (this : <b>access</b> Carnivore) <b>return</b> int <b>is</b> <b>abstract</b>;
   <b>end</b>;
   <b>use</b> Class_Carnivore;

   <b>package</b> Class_Domestic <b>is</b>
     <b>type</b> Domestic <b>is</b> <b>limited</b> <b>interface</b>;
     <b>pragma</b> Import (CPP, Domestic);

     <b>procedure</b> Set_Owner
       (this : <b>access</b> Domestic;
        Name : Interfaces.C.Strings.chars_ptr) <b>is</b> <b>abstract</b>;
   <b>end</b>;
   <b>use</b> Class_Domestic;

   <b>package</b> Class_Animal <b>is</b>
     <b>type</b> Animal <b>is</b> <b>tagged</b> <b>limited</b> <b>record</b>
       Age_Count : <b>aliased</b> int;
     <b>end</b> <b>record</b>;
     <b>pragma</b> Import (CPP, Animal);

     <b>procedure</b> Set_Age (this : <b>access</b> Animal; New_Age : int);
     <b>pragma</b> Import (CPP, Set_Age, &quot;_ZN6Animal7Set_AgeEi&quot;);
   <b>end</b>;
   <b>use</b> Class_Animal;

   <b>package</b> Class_Dog <b>is</b>
     <b>type</b> Dog <b>is</b> <b>new</b> Animal <b>and</b> Carnivore <b>and</b> Domestic <b>with</b> <b>record</b>
       Tooth_Count : <b>aliased</b> int;
       Owner : Interfaces.C.Strings.chars_ptr;
     <b>end</b> <b>record</b>;
     <b>pragma</b> Import (CPP, Dog);

     <b>function</b> Number_Of_Teeth (this : <b>access</b> Dog) <b>return</b> int;
     <b>pragma</b> Import (CPP, Number_Of_Teeth, &quot;_ZN3Dog15Number_Of_TeethEv&quot;);

     <b>procedure</b> Set_Owner
       (this : <b>access</b> Dog; Name : Interfaces.C.Strings.chars_ptr);
     <b>pragma</b> Import (CPP, Set_Owner, &quot;_ZN3Dog9Set_OwnerEPc&quot;);

     <b>function</b> New_Dog <b>return</b> Dog&apos;Class;
     <b>pragma</b> CPP_Constructor (New_Dog, &quot;_ZN3DogC1Ev&quot;);
   <b>end</b>;
   <b>use</b> Class_Dog;

<b>end</b> animals_h;
</pre>


<p>As you can see, C++ classes are mapped to Ada tagged types and even interfaces
when possible. Another advantage of directly using the C++ compiler to
generate bindings is that the information about C++ mangling is readily
available and can be generated easily, while writing it manually can be
tedious and error prone.</p>



<p>The C++ mangling is the low-level name chosen by the C++ compiler for a given
function, such as &#8220;_ZN3Dog9Set_OwnerEPc&#8221; in the case of procedure
Class_Dog.Set_Owner in the example above.</p>

<p>In the next Gem, we will explore in more detail how the CPP_Constructor pragma
works and how to combine it with Ada features.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/03/09/gem-60-generating-ada-bindings-for-c-headers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gem #59: Generating Ada bindings for C headers</title>
		<link>http://www.adacore.com/2009/02/23/gem-59/</link>
		<comments>http://www.adacore.com/2009/02/23/gem-59/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 11:00:29 +0000</pubDate>
		<dc:creator>AdaCore</dc:creator>
		
		<category><![CDATA[Ada / Ada 2005]]></category>

		<category><![CDATA[Development Log]]></category>

		<category><![CDATA[Devt log - Gem of the Week]]></category>

		<guid isPermaLink="false">http://www2.adacore.com/?p=2596</guid>
		<description><![CDATA[Ada Gem #59 &#8212; One of the delicate areas of Ada that is often unfamiliar to developers
is how to intermix Ada code with other programming languages. While Ada
provides very powerful and complete capabilities to interface with other
compiled languages such as C, C++, and Fortran, writing the Ada glue code
that enables a programmer to use complex and large APIs can be tedious and
error-prone.<br/>
In this Gem, we will explore a new tool provided by AdaCore to automate the
interface generation of C header files through the compiler.
]]></description>
			<content:encoded><![CDATA[<h3>Let&#8217;s get started&#8230;</h3><br/>


<p>GNAT now comes with a new experimental binding generator for C and C++
headers which is intended to do 95% of the tedious work of generating
Ada specs from C or C++ header files. Note that this is still a work in
progress, not designed to generate 100% correct Ada specs.</p>



<p>The code generated uses the Ada 2005 syntax, making it
easier to interface with other languages than did previous versions of Ada,
in particular via the generation of limited with clauses and anonymous
access types.</p>



<p>In this Gem, we will focus on the generation of C bindings. Bindings to
C++ will be addressed in a future Gem.</p>




<p><strong>Running the binding generator</strong></p>



<p>The binding generator is part of the GCC compiler that comes with recent
versions of GNAT and can be invoked via the -fdump-ada-spec switch, which
generates Ada spec files for the header files specified on the command
line, and all header files needed by these files transitivitely. For example:</p>

<pre>
$ g++ -c -fdump-ada-spec -C /usr/include/time.h
$ gcc -c -gnat05 *.ads
</pre>


<p>generates, under GNU/Linux, the following files: time_h.ads,
bits_time_h.ads, stddef_h.ads, bits_types_h.ads, which
correspond to the files /usr/include/time.h,
/usr/include/bits/time.h, etc&#8230;, and then compiles these Ada specs in Ada 2005 mode.</p>



<p>The -C switch tells GCC to extract comments from headers
and attempt to generate corresponding Ada comments.</p>



<p>If you want to generate a single Ada file and not the transitive closure, you can use the -fdump-ada-spec-slim switch instead.</p>



<p>Note that we recommend, where possible, to use the G++ driver to
generate bindings, even for most C headers, since this will in general
generate better Ada specs. If G++ doesn&#8217;t work on your C headers
because of incompatibilities between C and C++, then you can fall back on
using GCC instead.</p>



<p>For an example of better bindings generated from the C++ front end,
the name of the parameters (when available) are actually ignored by the C
front end. Consider the following C header:</p>

<pre>
extern void foo (int variable);
</pre>


<p>With the C front end, &#8220;variable&#8221; is ignored, and the above is handled as:</p>

<pre>
extern void foo (int);
</pre>


<p>generating the following subprogram specification:</p>

<pre>
<b>procedure</b> foo (param1 : int);
</pre>


<p>With the C++ front end, the name is available, and we generate:</p>

<pre>
<b>procedure</b> foo (variable : int);
</pre>


<p>In some cases, the generated bindings will be more complete or more meaningful
when defining macros, which you can do via the -D switch. This
is for example the case with Xlib.h under GNU/Linux:</p>

<pre>
g++ -c -fdump-ada-spec -DXLIB_ILLEGAL_ACCESS -C /usr/include/X11/Xlib.h
</pre>


<p>The above will generate more complete bindings than a straight call without
the -DXLIB_ILLEGAL_ACCESS switch.
</p>


<p>In other cases, it is not possible to parse a header file in a stand-alone
manner, because other include files need to be included first. In this
case, the solution is to create a small header file including the needed
#include and possible #define directives. For example, to
generate Ada bindings for readline/readline.h, you first need to
include stdio.h, so you can create a file with the following two
lines in, for example, readline1.h:</p>

<pre>
#include &lt;stdio.h&gt;
#include &lt;readline/readline.h&gt;
</pre>


<p>and then generate Ada bindings from this file:</p>

<pre>
$ g++ -c -fdump-ada-spec readline1.h
</pre>


<p>In a future Gem we will talk about generating similar Ada bindings for
C++ headers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adacore.com/2009/02/23/gem-59/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
